Last active
March 14, 2021 18:07
-
-
Save masked-rpgmaker/0130d3188a3e0c00a217f7bf761b103f to your computer and use it in GitHub Desktop.
Script de fases do dia para o RPG Maker VX Ace
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#============================================================================== | |
# 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