Skip to content

Instantly share code, notes, and snippets.

@masked-rpgmaker
Last active March 14, 2021 18:07
Show Gist options
  • Save masked-rpgmaker/0130d3188a3e0c00a217f7bf761b103f to your computer and use it in GitHub Desktop.
Save masked-rpgmaker/0130d3188a3e0c00a217f7bf761b103f to your computer and use it in GitHub Desktop.
Script de fases do dia para o RPG Maker VX Ace
#==============================================================================
# Fases do dia | v1.1.1 | por Brandt
#
# para RPG Maker VX Ace
#------------------------------------------------------------------------------
# O script cria um sistema de dia e noite baseando-se no horário do computador.
# Conforme o horário for atingindo os números definidos nas configurações, o
# tom da tela muda para o tom definido para o horário. O tom da tela muda
# gradualmente, interpolando entre os tons de cada período do dia.
#==============================================================================
#==============================================================================
# Features
#------------------------------------------------------------------------------
# - Configurável: é possível criar quantos períodos do dia quanto desejado,
# além de atribuir uma duração específica para cada um;
#
# - Interação com o Khas Awesome Light Effects: Os scripts são compatíveis!
# Basta que o script do Khas esteja presente no projeto que esse se ajusta
# automaticamente para usar funções compatíveis;
#
# - Amigável a eventos: O script permite alterar valores de variáveis e
# switches do jogo conforme os períodos do dia acontecem.
#==============================================================================
#==============================================================================
# Modo de uso
#------------------------------------------------------------------------------
# Só configure o script, logo abaixo, e tá tudo certo.
# Em alguns casos, pode ser interessante fixar o período do dia (ou ignorar o
# período) em alguns mapas (dungeons, interiores, ...). Para isso, adicione às
# notas do mapa o seguinte:
#
# <notime>
#
# Ou, para fixar o mapa em um período:
#
# <time: ...>
#
# Trocando o "..." pelo nome do período, configurado no script.
# Maiúsculas e minúsculas e espaços em branco não fazem diferença.
#==============================================================================
($modules ||= {})[:day_and_night] = "1.1.1"
#==============================================================================
# ** Configurações
#==============================================================================
module DayAndNight
#--------------------------------------------------------------------------
# * Modo de cálculo do tempo
#
# Valores possíveis:
# :computer ~> Usa o relógio do computador
# :game ~> Usa um relógio interno do jogo
#--------------------------------------------------------------------------
TIME_MODE = :game
#--------------------------------------------------------------------------
# * Multiplicador de tempo no jogo
#
# Ignore a menos que esteja usando TIME_MODE = :game
#--------------------------------------------------------------------------
TIME_MULTIPLIER = 60*60
#--------------------------------------------------------------------------
# * Hora inicial do jogo
#
# Ignore a menos que esteja usando TIME_MODE = :game
#--------------------------------------------------------------------------
INIT_HOUR = 12
#--------------------------------------------------------------------------
# * Atraso em frames da transição entre os períodos.
# Serve para evitar mudanças demasiado bruscas entre as tonalidades da
# tela.
#--------------------------------------------------------------------------
PERIOD_TRANSITION_DELAY = 60
#--------------------------------------------------------------------------
# * ID da variável do jogo que recebe a hora atual, seja no relógio interno
# do jogo ou no do computador. (0 = Nenhuma)
#--------------------------------------------------------------------------
HOUR_VARIABLE_ID = 0
#--------------------------------------------------------------------------
# * Períodos
#
# Cada período é composto, primariamente, por um nome identificador, uma
# hora de início, seguindo o sistema 24h, e uma tonalidade para a tela.
# Também é possível configurar uma switch para ser ativada enquanto o
# período estiver em efeito.
# Os períodos não precisam estar em ordem.
#
# Para adicionar novos períodos, copie um dos existentes e modifique os
# valores. Note que, mesmo se dois períodos tiverem o mesmo horário,
# apenas um deles será ativado por vez.
#--------------------------------------------------------------------------
PERIODS = {
#----------------------------------------------------------------------
# Nascer do Sol
#----------------------------------------------------------------------
sunrise: {
# Hora de início
start: 6,
# Tonalidade da tela (Vermelho, Verde, Azul[, Cinza])
tone: [-110, -110, -110],
# Switch que ativa
switch: 16
},
#----------------------------------------------------------------------
# Manhã
#----------------------------------------------------------------------
morning: {
# Hora de início
start: 7,
# Tonalidade da tela (Vermelho, Verde, Azul[, Cinza])
tone: [0, -5, -50],
# Switch que ativa
switch: 17
},
#----------------------------------------------------------------------
# Meio-Dia
#----------------------------------------------------------------------
noon: {
# Hora de início
start: 12,
# Tonalidade da tela (Vermelho, Verde, Azul[, Cinza])
tone: [0, 0, 0],
# Switch que ativa
switch: 18
},
#----------------------------------------------------------------------
# Tarde
#----------------------------------------------------------------------
afternoon: {
# Hora de início
start: 16,
# Tonalidade da tela (Vermelho, Verde, Azul[, Cinza])
tone: [0, -30, -55],
# Switch que ativa
switch: 19
},
#----------------------------------------------------------------------
# Pôr do Sol
#----------------------------------------------------------------------
sunset: {
# Hora de início
start: 18,
# Tonalidade da tela (Vermelho, Verde, Azul[, Cinza])
tone: [-100, -130, -155],
# Switch que ativa
switch: 20
},
#----------------------------------------------------------------------
# Noite
#----------------------------------------------------------------------
night: {
# Hora de início
start: 19,
# Tonalidade da tela (Vermelho, Verde, Azul[, Cinza])
tone: [-175, -175, -125],
# Switch que ativa
switch: 21
},
}
#==============================================================================
# ** Fim das Configurações
#------------------------------------------------------------------------------
# Daqui pra baixo, é festa. Não é recomendado mexer nessa parte, a menos que se
# saiba bem o que está fazendo.
#==============================================================================
module_function
#--------------------------------------------------------------------------
# * Obtém uma lista com os nomes de cada período configurado no script,
# em ordem de horário
#--------------------------------------------------------------------------
def periods
return PERIODS.keys.sort_by do |k|
PERIODS[k][:hour]
end
end
#--------------------------------------------------------------------------
# * Obtém o enésimo período, por ordem de horário
#--------------------------------------------------------------------------
def nth_period(n)
return periods[n] || raise("Período do dia ##{n} não encontrado")
end
#--------------------------------------------------------------------------
# * Obtém uma informação de determinado período pelo nome ou pelo índice
# period : Nome ou índice do período
# info : Chave de informação na configuração do script
#--------------------------------------------------------------------------
def period_info(period, info)
period = nth_period(period) if period.is_a?(Integer)
return PERIODS[period][info]
end
private :period_info
#--------------------------------------------------------------------------
# * Obtém o tom da tela para determinado período
# period : Nome do período na configuração do script
#--------------------------------------------------------------------------
def tone(period)
return Tone.new(0, 0, 0, 0) if period.nil?
return Tone.new(*period_info(period, :tone))
end
#--------------------------------------------------------------------------
# * Obtém o horário de início de determinado período
# period : Nome do período na configuração do script
#--------------------------------------------------------------------------
def hour(period)
period_info(period, :start)
end
#--------------------------------------------------------------------------
# * Obtém a switch ativada por determinado período
# period : Nome do período na configuração do script
#--------------------------------------------------------------------------
def switch(period)
period_info(period, :switch)
end
#--------------------------------------------------------------------------
# * Determina se deve usar o relógio do computador com o script
#--------------------------------------------------------------------------
def real_time?
case TIME_MODE
when :computer
return true
when :game
return false
else
raise 'Fases do dia: Configuração inválida em `TIME_MODE`'
end
end
end
#==============================================================================
# ** Game_Clock
#------------------------------------------------------------------------------
# Esta classe gerencia o relógio interno do jogo. Serve apenas para quando a
# configuração TIME_MODE for igual a :game
#==============================================================================
class Game_Clock
#--------------------------------------------------------------------------
# * Variáveis públicas
#--------------------------------------------------------------------------
attr_reader :time # Tempo decorrido desde o início do jogo
attr_reader :period # Período do dia atual
#--------------------------------------------------------------------------
# * Inicialização do objeto
#--------------------------------------------------------------------------
def initialize
initialize_time
initialize_period
update
end
#--------------------------------------------------------------------------
# * Inicializa o contador de tempo do relógio
#--------------------------------------------------------------------------
def initialize_time
if DayAndNight.real_time?
@time = Time.now
else
@creation_time = Time.now
@time = Time.at(0)
@offset = 0.0
fast_forward(DayAndNight::INIT_HOUR)
end
end
#--------------------------------------------------------------------------
# * Inicializa a variável de controle do período atual
#--------------------------------------------------------------------------
def initialize_period
@period = -1
DayAndNight.periods.each_with_index do |period, i|
break if DayAndNight.hour(period) > @time.hour
@period = i
end
end
#--------------------------------------------------------------------------
# * Serialização do objeto
#--------------------------------------------------------------------------
def marshal_dump
[@time.to_i, @period]
end
#--------------------------------------------------------------------------
# * Desserialização do objeto
# data : Dados lidos do arquivo
#--------------------------------------------------------------------------
def marshal_load(data)
@offset, @period = data
if DayAndNight.real_time?
@time = Time.now
else
@creation_time = Time.now
@time = Time.at(0)
end
end
#--------------------------------------------------------------------------
# * Atualiza o relógio do jogo e a variável ligada a ele
#--------------------------------------------------------------------------
def update
update_time
update_period
update_game_variable unless DayAndNight::HOUR_VARIABLE_ID.zero?
end
#--------------------------------------------------------------------------
# * Atualiza o tempo do jogo
#--------------------------------------------------------------------------
def update_time
if DayAndNight.real_time?
@time = Time.now
else
delta = Time.now - @creation_time
@time = Time.at(delta.to_f * DayAndNight::TIME_MULTIPLIER) + @offset
end
end
#--------------------------------------------------------------------------
# * Avança o relógio para uma hora dada
# hour : Hora do dia desejada
#--------------------------------------------------------------------------
def fast_forward(hour)
delta_d = @time.hour <= hour ? 1 : 0
delta_h = hour - @time.hour
delta_m = -@time.min
delta_s = -@time.sec
delta = ((24 * delta_d + delta_h) * 60 + delta_m) * 60 + delta_s
@offset += delta
end
#--------------------------------------------------------------------------
# * Atualiza a variável do jogo que guarda a hora atual
#--------------------------------------------------------------------------
def update_game_variable
$game_variables[DayAndNight::HOUR_VARIABLE_ID] = time.hour
end
#--------------------------------------------------------------------------
# * Próximo período do dia
#--------------------------------------------------------------------------
def next_period
(@period + 1) % DayAndNight.periods.size
end
#--------------------------------------------------------------------------
# * Determina se deveria trocar de período
#--------------------------------------------------------------------------
def should_change_periods?
if next_period < @period
return false unless @time.hour < DayAndNight.hour(@period)
return @time.hour >= DayAndNight.hour(next_period)
end
return true if @time.hour < DayAndNight.hour(@period)
return @time.hour >= DayAndNight.hour(next_period)
end
#--------------------------------------------------------------------------
# * Determina o período atual do dia usando o relógio
#--------------------------------------------------------------------------
def update_period
return unless should_change_periods?
update_game_switches
@period = next_period
end
#--------------------------------------------------------------------------
# * Atualiza as switches que identificam os períodos do dia
#--------------------------------------------------------------------------
def update_game_switches
$game_switches[DayAndNight.switch(@period)] = false
$game_switches[DayAndNight.switch(next_period)] = true
end
end
#==============================================================================
# ** DataManager
#------------------------------------------------------------------------------
# Este módulo gerencia o jogo e objetos do banco de dados utilizados no jogo.
# Quase todas as variáveis globais são inicializadas no módulo.
# Modificado para salvar no arquivo de Save do jogo o relógio interno usado
# para controlar o sistema de dia e noite.
#==============================================================================
class << DataManager
#--------------------------------------------------------------------------
# * Criação dos objetos do jogo
#--------------------------------------------------------------------------
alias day_and_night_create_game_objects create_game_objects
def create_game_objects(*args, &block)
day_and_night_create_game_objects(*args, &block)
$game_clock = Game_Clock.new
end
#--------------------------------------------------------------------------
# * Salvar a criação de conteúdo
#--------------------------------------------------------------------------
alias day_and_night_make_save_contents make_save_contents
def make_save_contents(*args, &block)
contents = day_and_night_make_save_contents(*args, &block)
contents[:clock] = $game_clock
contents
end
#--------------------------------------------------------------------------
# * Extrair conteúdo salvo
#--------------------------------------------------------------------------
alias day_and_night_extract_save_contents extract_save_contents
def extract_save_contents(contents, *args, &block)
day_and_night_extract_save_contents(contents, *args, &block)
$game_clock = contents[:clock]
end
end
#==============================================================================
# ** Color
#------------------------------------------------------------------------------
# Classe usada para representar uma cor.
# Modificada para possibilitar obter uma cor a partir de um Tone, necessário
# para compatibilidade com o Khas Awesome Light Effects
#==============================================================================
class << Color
#--------------------------------------------------------------------------
# * Cria uma cor a partir de um Tone
# tone : Tone a ser usado de referência para a cor
#--------------------------------------------------------------------------
def from_tone(tone)
red = 0
green = 0
blue = 0
if tone.red < 0
red += tone.red
green -= tone.red
blue -= tone.red
else
red += tone.red * 2
end
if tone.green < 0
red -= tone.green
green += tone.green
blue -= tone.green
else
green += tone.green * 2
end
if tone.blue < 0
red -= tone.blue
green -= tone.blue
blue += tone.blue
else
blue += tone.blue * 2
end
alpha = tone.red.abs + tone.green.abs + tone.blue.abs
return Color.new(red, green, blue, alpha)
end
end
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# Esta classe gerencia o mapa. Inclui funções de rolagem e definição de
# passagens. A instância desta classe é referenciada por $game_map.
# Modificado para expor as notas do mapa (Isso devia ser padrão!!)
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Obtém as notas do mapa
#--------------------------------------------------------------------------
def note
@map.note
end
end
#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
# Esta classe reune os sprites da tela de mapa e tilesets. Esta classe é
# usada internamente pela classe Scene_Map.
# Modificada para atualizar a tonalidade da tela de acordo com o período do
# dia. Na verdade, o ideal era modificar a Game_Map, mas assim não seria
# possível utilizar o script junto do Khas Awesome Light Effects.
#==============================================================================
class Spriteset_Map
#--------------------------------------------------------------------------
# * Constantes (Expressões regulares)
#--------------------------------------------------------------------------
MAP_NOTIME_TAG = /<\s*no(?:\s*|-|_?)time\s*>/i
MAP_TIME_FIX_TAG = /<\s*time\s*(?:\:|=)\s*(?:\:)?(\S+)\s*>/i
#--------------------------------------------------------------------------
# * Inicialização do objeto
#--------------------------------------------------------------------------
alias day_and_night_initialize initialize
def initialize(*args, &block)
day_and_night_initialize(*args, &block)
refresh_period_tone
end
#--------------------------------------------------------------------------
# * Obtém o período atual do mapa
#--------------------------------------------------------------------------
def map_period
return nil if $game_map.note =~ MAP_NOTIME_TAG
if $game_map.note =~ MAP_TIME_FIX_TAG
period = $1.to_sym
unless DayAndNight.periods.include?(period)
map_id = $game_map.map_id
raise "Fases do dia: Período inválido `#{period}` no mapa #{map_id}"
end
return period
end
return $game_clock.period
end
#--------------------------------------------------------------------------
# * Obtém o Tone para o período atual do mapa
#--------------------------------------------------------------------------
def map_tone
return DayAndNight.tone(map_period)
end
#--------------------------------------------------------------------------
# * Inicializa a tela com o tem do período atual do dia
#--------------------------------------------------------------------------
def refresh_period_tone
if defined? $game_map.effect_surface
color = Color.from_tone(map_tone)
$game_map.effect_surface.set_color(color.red, color.green, color.blue)
$game_map.effect_surface.set_alpha(color.alpha)
else
$game_map.screen.start_tone_change(map_tone, 0)
end
end
#--------------------------------------------------------------------------
# * Atualização da tela
#--------------------------------------------------------------------------
alias day_and_night_update update
def update(*args, &block)
update_period_tone
day_and_night_update(*args, &block)
end
#--------------------------------------------------------------------------
# * Atualiza o período do dia
#--------------------------------------------------------------------------
def update_period_tone
return refresh_period_tone if @map_id != $game_map.map_id
return unless should_update_period_tone?
delay = DayAndNight::PERIOD_TRANSITION_DELAY
if defined? $game_map.effect_surface
color = Color.from_tone(map_tone)
r, g, b, a = color.red, color.green, color.blue, color.alpha
$game_map.effect_surface.change_color(delay, r, g, b, a)
else
$game_map.screen.start_tone_change(map_tone, delay)
end
end
#--------------------------------------------------------------------------
# * Determina se deveria atualizar o tom do período
# Por padrão, atualiza a cada 15 minutos
#--------------------------------------------------------------------------
def should_update_period_tone?
return @period != map_period
end
end
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# Esta classe executa o processamento da tela de mapa. Modificado para
# atualizar o relógio do jogo.
#==============================================================================
class Scene_Map < Scene_Base
#--------------------------------------------------------------------------
# * Atualização da tela
#--------------------------------------------------------------------------
alias day_and_night_update update
def update
day_and_night_update
$game_clock.update
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment