#===============================================================================
# ■ [VA] 带有奇怪功能的打字声效
# Cirno
#-------------------------------------------------------------------------------
# 这个脚本能在各种对话中播放打字声效
# * 在 配置部分 中自定义声效种类、频率
# * 使用 \S[编号] 在对话途中改变声效
# * 使用 type_effects("效果1", "效果2", ...) 设置声效特殊效果
# ① 音量、声调的渐变
# ② 对话显示速度变化和震动效果
#===============================================================================( e+ K- F5 k$ c4 ^6 W
# 以下是配置部分
#===============================================================================
module Cirno
module TypingSound
#--------------------------------------------------------------------------
# * 默认设置
#--------------------------------------------------------------------------
# 脚本启用的开关编号
ENABLE_SWITCH = 1
# 默认声效,格式为 [名字, 音量, 节奏]
DEFAULT_SOUND = ["Cursor1", 100, 100]
# 是否用第一行来判断人物
# true: 按照第一行的名字在NAME_SOUNDS里选择对应的声效
# false: 按照脸图的文件名和图像编号,在FACE_DEFAULT_SOUNDS和FACE_PATTERN_SOUNDS中选择
FIRST_LINE_AS_CHARACTER = false
#--------------------------------------------------------------------------
# * 声效使用列表
#--------------------------------------------------------------------------
SOUND_TABLE = {
1 => ["Cursor2", 100, 100], # 嘟声
2 => ["Cursor2", 100, 150], # 尖细的声音
3 => ["Cursor2", 100, 50], # 低沉的声音
60 => ["", 100, 100] # 文件设置为空的时候表示无音效
}
#--------------------------------------------------------------------------
# * 文字停顿设置
#--------------------------------------------------------------------------
# 遇到这些标点符号的时候停顿更久
PUNCS = ",.?!" + ",。?!—…~"
# 普通字符的停顿时间
DEFAULT_CHAR_WAITING = 3
# 遇到标点符号的停顿时间
DEFAULT_PUNC_WAITING = 10
# 显示多少个字播放一次声效
CHARACTERS_FOR_SOUND = 3
#--------------------------------------------------------------------------
# * 第一行名字与声效的关联
#--------------------------------------------------------------------------
NAME_SOUNDS = {
"拉尔夫" => 3
}
#--------------------------------------------------------------------------
# * 脸图与声效的关联
#--------------------------------------------------------------------------
FACE_DEFAULT_SOUNDS = {
"Actor1" => 1 # 当脸图为Actor1,默认使用1号声音
}
FACE_PATTERN_SOUNDS = {
["Actor1", 3] => 2, # 当脸图为Actor1中编号3(第一行最后),使用2号声效
["Actor1", 7] => 3, # 当脸图为Actor1中编号7(第二行最后),使用3号声效
}
#===============================================================================( e+ K- F5 k$ c4 ^6 W
# 以上是配置部分
#===============================================================================
@@effects = []
def self.sound_path
"Audio/SE/"
end
def self.set_effects(*args)
@@effects = args
end
def self.reset
@@char_waiting = DEFAULT_CHAR_WAITING
@@punc_waiting = DEFAULT_PUNC_WAITING
@@volume_transition_speed = 0
@@volume_transition_total = 0
@@pitch_transition_speed = 0
@@pitch_transition_total = 0
@@wait_factor = 1.0
@@shaking = false
@@character_counter = -1
apply_effects
end
def self.apply_effects
@@effects.each { |effect|
if /pitch_v\((.*)\)/ === effect
@@pitch_transition_total += effect[8..-2].to_f
end
if /pitch_t\((.*)\)/ === effect
@@pitch_transition_speed += effect[8..-2].to_f
end
if /volume_v\((.*)\)/ === effect
@@volume_transition_total += effect[9..-2].to_f
end
if /volume_t\((.*)\)/ === effect
@@volume_transition_speed += effect[9..-2].to_f
end
if /speed\((.*)\)/ === effect
@@wait_factor /= effect[6..-2].to_f
end
if /shake/ === effect
@@shaking = true
end
}
@@effects = []
end
def self.get_character_wait(c)
if PUNCS.include?(c)
w = DEFAULT_PUNC_WAITING
else
w = DEFAULT_CHAR_WAITING
end
w *= @@wait_factor
w.to_i
end
def self.play_sound_array(sound)
return unless $game_switches[ENABLE_SWITCH]
@@character_counter += 1
@@character_counter = 0 if @@character_counter == CHARACTERS_FOR_SOUND
return if @@character_counter != 0 && !@@shaking
file = sound_path + sound[0]
volume = sound[1]
volume += @@volume_transition_total
@@volume_transition_total += @@volume_transition_speed
pitch = sound[2]
pitch += @@pitch_transition_total
@@pitch_transition_total += @@pitch_transition_speed
volume = 0 if volume < 0
Audio.se_play(file, volume, pitch) unless sound[0].empty?
shake_screen if @@shaking
end
def self.shake_screen
$game_map.screen.start_shake(3, 10, 20)
end
def self.play_default
play_sound_array(DEFAULT_SOUND)
end
def self.play_index(i)
play_sound_array(SOUND_TABLE[i])
end
def self.play_face(face_name, face_index)
pattern_key = [face_name, face_index]
if FACE_PATTERN_SOUNDS.has_key?(pattern_key)
play_index(FACE_PATTERN_SOUNDS[pattern_key])
elsif FACE_DEFAULT_SOUNDS.has_key?(face_name)
play_index(FACE_DEFAULT_SOUNDS[face_name])
else
play_default
end
end
def self.play_name(name)
if NAME_SOUNDS.has_key?(name)
play_index(NAME_SOUNDS[name])
else
play_default
end
end
end
end
class Game_Interpreter
def type_effects(*args)
Cirno::TypingSound.set_effects(*args)
end
end
class Window_Message
alias cirno_20161212_clear_flags clear_flags
def clear_flags
cirno_20161212_clear_flags
@sound_index = 0
Cirno::TypingSound.reset
end
alias cirno_20161212_process_escape_character process_escape_character
def process_escape_character(code, text, pos)
cirno_20161212_process_escape_character(code, text, pos)
case code.upcase
when 'S'
@sound_index = obtain_escape_param(text).to_i
end
end
def play_typing_sound
if @sound_index == 0
if Cirno::TypingSound::FIRST_LINE_AS_CHARACTER
Cirno::TypingSound.play_name($game_message.texts[0])
else
Cirno::TypingSound.play_face($game_message.face_name, $game_message.face_index)
end
else
Cirno::TypingSound.play_index(@sound_index)
end
end
alias cirno_20161212_process_normal_character process_normal_character
def process_normal_character(c, pos)
play_typing_sound
cirno_20161212_process_normal_character(c, pos)
end
def process_character(c, text, pos)
@current_character = c
super(c, text, pos)
end
def wait_for_one_character
update_show_fast
unless @show_fast || @line_show_fast
if $game_switches[Cirno::TypingSound::ENABLE_SWITCH]
w = Cirno::TypingSound.get_character_wait(@current_character)
w.times { Fiber.yield }
else
Fiber.yield
end
end
end
end