#==============================================================================
# ■ VX Ace 한영 이름 입력 스크립트 (결과창 가로 중앙 정렬 버전)
#------------------------------------------------------------------------------
# 원본: TeamHusH / Heircoss
# 수정: 결과창도 가로 중앙 정렬 + OK 89번 + 두 창 붙임
#==============================================================================
class Window_NameEdit < Window_Base
# 한글 조합 로직 (원본 그대로)
CONSO = ["ㄱ","ㄲ","ㄳ","ㄴ","ㄵ","ㄶ","ㄷ","ㄸ","ㄹ","ㄺ","ㄻ","ㄼ","ㄽ","ㄾ","ㄿ","ㅀ","ㅁ","ㅂ","ㅃ","ㅄ","ㅅ","ㅆ","ㅇ","ㅈ","ㅉ","ㅊ","ㅋ","ㅌ","ㅍ","ㅎ"]
HEAD = ["ㄱ","ㄲ","ㄴ","ㄷ","ㄸ","ㄹ","ㅁ","ㅂ","ㅃ","ㅅ","ㅆ","ㅇ","ㅈ","ㅉ","ㅊ","ㅋ","ㅌ","ㅍ","ㅎ"]
TABLE = ["ㄱ","ㄲ","ㄳ","ㄴ","ㄵ","ㄶ","ㄷ","ㄹ","ㄺ","ㄻ","ㄼ","ㄽ","ㄾ","ㄿ","ㅀ","ㅁ","ㅂ","ㅄ","ㅅ","ㅆ","ㅇ","ㅈ","ㅊ","ㅋ","ㅌ","ㅍ","ㅎ"]
TABLE_SIDE = ["ㄱ","ㄴ","ㄹ","ㅂ"]
ANOTHER_TABLE_SIDE = [[nil,"ㅅ"],["ㅈ","ㅎ"],["ㄱ","ㅁ","ㅂ","ㅅ","ㅌ","ㅍ","ㅎ"],[nil,"ㅅ"]]
VOWEL = ["ㅏ","ㅐ","ㅑ","ㅒ","ㅓ","ㅔ","ㅕ","ㅖ","ㅗ","ㅘ","ㅙ","ㅚ","ㅛ","ㅜ","ㅝ","ㅞ","ㅟ","ㅠ","ㅡ","ㅢ","ㅣ"]
COM_VOWEL = ["ㅗ","ㅜ","ㅡ"]
ANOTHER_COM_VOWEL = [["ㅏ","ㅐ","ㅣ"],["ㅓ","ㅔ","ㅣ"],["ㅣ"]]
attr_reader :name, :index, :max_char
def initialize(actor, max_char)
# 가로 중앙 정렬 적용
window_width = 368
window_height = 128
x = (Graphics.width - window_width) / 2
y = 30 # ← 원하는 대로 Y값 조정 가능 (30이 현재 값)
super(x, y, window_width, window_height)
@actor = actor
@prompt = []
@max_char = max_char
name_array = actor.name.split(
@name = name_array.dup
@default_name = name_array.dup
@index = @name.size
deactivate
refresh
end
def restore_default
@name = @default_name.dup
@index = @name.size
refresh
return !@name.empty?
end
def add(ch)
@prompt << ch
refresh
end
def back
@prompt.empty? ? @name.pop : @prompt.pop
refresh
end
def face_width; 96; end
def char_width
text_size($game_system.japanese? ? "가가" : "AA").width
end
def left
name_center = (contents_width + face_width) / 2
name_width = (@max_char + 1) * char_width
[name_center - name_width / 2, contents_width - name_width].min
end
def item_rect(index)
Rect.new(left + index * char_width, 36, char_width, line_height)
end
def underline_rect(index)
rect = item_rect(index)
rect.x += 1; rect.y += rect.height - 4; rect.width -= 2; rect.height = 2
rect
end
def underline_color
color = normal_color; color.alpha = 48; color
end
def draw_underline(index)
contents.fill_rect(underline_rect(index), underline_color)
end
def draw_char(index)
rect = item_rect(index); rect.x -= 1; rect.width += 4
change_color(normal_color)
draw_text(rect, @name[index] || "")
end
def refresh
contents.clear
draw_actor_face(@actor, 0, 0)
count_text = "#{@name.size} / #{@max_char}"
change_color(system_color)
draw_text(4, 4, contents.width - 8, line_height, count_text, 2)
change_color(normal_color)
name = prompt_to_letter
if @name.size == @max_char
@prompt = []; name = ""; @index = @name.size - 1
else
@index = @name.size
end
for i in 0...@name.size
self.contents.draw_text(item_rect(i), @name[i], 1)
end
self.contents.draw_text(item_rect(@name.size), name, 1)
cursor_rect.set(item_rect(@index))
end
#==================== 한글 조합 로직 (원본 그대로) ====================
def prompt_to_letter
case @prompt.size
when 0; return ""
when 1; return @prompt[0]
when 2; return first_phase
when 3; return second_phase
when 4; return third_phase
when 5; return fourth_phase
when 6; return fifth_phase
end
end
def first_phase
if CONSO.include?(@prompt[0])
CONSO.include?(@prompt[1]) ? (c0, c1 = conso_plus_conso) : (return conso_plus_vowel)
else
c0, c1 = vowel_plus_vowel
end
c1.nil? ? c0 : (@name << @prompt.shift; @prompt[0])
end
def second_phase
if CONSO.include?(@prompt[0])
if CONSO.include?(@prompt[1])
if CONSO.include?(@prompt[2])
@name << conso_plus_conso(@prompt.shift, @prompt.shift)
else
@name << @prompt.shift
return conso_plus_vowel
end
else
TABLE.include?(@prompt[2]) ? (return conso_plus_vowel_plus_table) : begin
c0, c1 = vowel_plus_vowel(@prompt[1], @prompt[2])
c1.nil? ? conso_plus_vowel(@prompt[0],c0) : (@name << conso_plus_vowel(@prompt.shift, @prompt.shift))
end
end
else
@name << vowel_plus_vowel(@prompt.shift, @prompt.shift)
end
@prompt[0]
end
def third_phase
if CONSO.include?(@prompt[2])
if CONSO.include?(@prompt[3])
c0, c1 = conso_plus_conso(@prompt[2], @prompt[3])
c1.nil? ? conso_plus_vowel_plus_table(@prompt[0], @prompt[1], c0) : (@name << conso_plus_vowel_plus_table(@prompt.shift, @prompt.shift, @prompt.shift))
else
conso, vowel = @prompt.shift, @prompt.shift
@name << conso_plus_vowel(conso, vowel)
return conso_plus_vowel
end
else
TABLE.include?(@prompt[3]) ? conso_plus_vowel_plus_table(@prompt[0], vowel_plus_vowel(@prompt[1], @prompt[2]), @prompt[3]) : begin
conso = @prompt.shift
vowel = vowel_plus_vowel(@prompt.shift, @prompt.shift)
@name << conso_plus_vowel(conso, vowel)
end
end
@prompt[0]
end
def fourth_phase
if CONSO.include?(@prompt[4])
if CONSO.include?(@prompt[2])
conso = @prompt.shift; vowel = @prompt.shift
table = conso_plus_conso(@prompt.shift,@prompt.shift)
@name << conso_plus_vowel_plus_table(conso, vowel, table)
else
c0, c1 = conso_plus_conso(@prompt[3], @prompt[4])
c1.nil? ? conso_plus_vowel_plus_table(@prompt[0], vowel_plus_vowel(@prompt[1], @prompt[2]), c0) : begin
conso = @prompt.shift; vowel = vowel_plus_vowel(@prompt.shift, @prompt.shift); table = @prompt.shift
@name << conso_plus_vowel_plus_table(conso, vowel, table)
end
end
else
@name << second_phase
@prompt = @prompt[3..4]
return first_phase
end
@prompt[0]
end
def fifth_phase
if CONSO.include?(@prompt[5])
conso = @prompt.shift
vowel = vowel_plus_vowel(@prompt.shift, @prompt.shift)
table = conso_plus_conso(@prompt.shift, @prompt.shift)
@name << conso_plus_vowel_plus_table(conso, vowel, table)
else
@name << third_phase
@prompt = @prompt[4..5]
return first_phase
end
@prompt[0]
end
def conso_plus_conso(c0 = @prompt[0], c1 = @prompt[1])
index0 = where?(TABLE_SIDE, c0)
if index0 && (index1 = where?(ANOTHER_TABLE_SIDE[index0], c1))
index0 = where?(CONSO, c0)
CONSO[index0 + index1 + 1]
else
[c0, c1]
end
end
def vowel_plus_vowel(c0 = @prompt[0], c1 = @prompt[1])
index0 = where?(COM_VOWEL, c0)
if index0 && (index1 = where?(ANOTHER_COM_VOWEL[index0], c1))
index0 = where?(VOWEL, c0)
VOWEL[index0 + index1 + 1]
else
[c0, c1]
end
end
def conso_plus_vowel(c0 = @prompt[0], c1 = @prompt[1])
index0 = where?(HEAD, c0)
index1 = where?(VOWEL, c1)
[44032 + (588 * index0) + (28 * index1)].pack('U*')
end
def conso_plus_vowel_plus_table(c0 = @prompt[0], c1 = @prompt[1], c2 = @prompt[2])
index0 = where?(HEAD, c0)
index1 = where?(VOWEL, c1)
index2 = where?(TABLE, c2)
[44032 + (588 * index0) + (28 * index1) + index2 + 1].pack('U*')
end
def where?(array, c)
array.each_with_index { |item, i| return i if item == c }
nil
end
end
#==============================================================================
# ■ Window_NameInput (기존 그대로 유지)
#==============================================================================
class Window_NameInput < Window_Selectable
KOREAN_TABLE = [
'ㄱ','ㄴ','ㄷ','ㄹ','ㅁ', 'ㅛ','ㅕ','ㅑ','ㅐ','ㅔ',
'ㅂ','ㅅ','ㅇ','ㅈ','ㅊ', 'ㅗ','ㅓ','ㅏ','ㅣ',' ',
'ㅋ','ㅌ','ㅍ','ㅎ',' ', 'ㅠ','ㅜ','ㅡ',' ',' ',
' ',' ',' ',' ',' ', ' ',' ',' ',' ',' ',
'ㄲ',' ','ㄸ',' ',' ', ' ',' ',' ','ㅒ','ㅖ',
'ㅃ','ㅆ',' ','ㅉ', ' ', ' ',' ',' ',' ',' ',
'0','1','2','3','4', '!','#','$','%','&',
'5','6','7','8','9', '(',')','*','+','-',
'/','=','@','<','>', ':',';',' ',' ','OK',
' ',' ',' ',' ',' ', ' ',' ',' ',' ',' '
]
ENGLISH_TABLE = [
'A','B','C','D','E', 'a','b','c','d','e',
'F','G','H','I','J', 'f','g','h','i','j',
'K','L','M','N','O', 'k','l','m','n','o',
'P','Q','R','S','T', 'p','q','r','s','t',
'U','V','W','X','Y', 'u','v','w','x','y',
'Z','[',']','^','_', 'z','{','}','|','~',
'0','1','2','3','4', '!','#','$','%','&',
'5','6','7','8','9', '(',')','*','+','-',
'/','=','@','<','>', ':',';',' ',' ','OK',
' ',' ',' ',' ',' ', ' ',' ',' ',' ',' '
]
VER_LINE = 10
HOR_LINE = 10
CONFIRM = 89
def initialize(edit_window)
window_width = edit_window.width
window_height = fitting_height(VER_LINE + 1)
x = (Graphics.width - window_width) / 2
y = edit_window.y + edit_window.height - 0 # 결과창 바로 아래 붙임
super(x, y, window_width, window_height)
@edit_window = edit_window
@mode = :korean
@index = 0
refresh
update_cursor
activate
end
def current_table
@mode == :korean ? KOREAN_TABLE : ENGLISH_TABLE
end
def character
current_table[@index] || ""
end
def is_ok?
@index == CONFIRM
end
def item_rect(index)
rect = Rect.new
rect.x = index % HOR_LINE * 32 + (index % HOR_LINE / 5) * 16
rect.y = index / HOR_LINE * line_height
rect.width = 32
rect.height = line_height
rect
end
def refresh
contents.clear
for i in 0...current_table.size
rect = item_rect(i)
rect.x += 2
rect.width -= 4
contents.draw_text(rect, current_table[i], 1)
end
mode_text = @mode == :korean ? "Shift: 영문 모드" : "Shift: 한글 모드"
contents.font.size = 18
draw_text(12, contents.height - line_height - 12, contents.width - 24, line_height, mode_text, 2)
contents.font.size = Font.default_size
end
def update_cursor
cursor_rect.set(item_rect(@index))
end
def process_handling
return unless open? && active
process_jump if Input.trigger?(:A)
process_back if Input.repeat?(:B)
process_ok if Input.trigger?(:C)
if Input.trigger?(:SHIFT)
@mode = (@mode == :korean ? :english : :korean)
Sound.play_cursor
refresh
update_cursor
end
end
def cursor_down(wrap)
if @index < VER_LINE * HOR_LINE - HOR_LINE
@index += HOR_LINE
elsif wrap
@index -= VER_LINE * HOR_LINE - HOR_LINE
end
end
def cursor_up(wrap)
if @index >= HOR_LINE
@index -= HOR_LINE
elsif wrap
@index += VER_LINE * HOR_LINE - HOR_LINE
end
end
def cursor_right(wrap)
if @index % HOR_LINE < (HOR_LINE - 1)
@index += 1
elsif wrap
@index -= (HOR_LINE - 1)
end
end
def cursor_left(wrap)
if @index % HOR_LINE > 0
@index -= 1
elsif wrap
@index += (HOR_LINE - 1)
end
end
def process_jump
if @index != CONFIRM
@index = CONFIRM
Sound.play_cursor
end
end
def process_back
Sound.play_cancel if @edit_window.back
end
def process_ok
if is_ok?
on_name_ok
elsif !character.empty?
on_name_add
end
end
def on_name_add
@edit_window.add(character) ? Sound.play_ok : Sound.play_buzzer
end
def on_name_ok
if @edit_window.name.empty?
@edit_window.restore_default ? Sound.play_ok : Sound.play_buzzer
else
Sound.play_ok
call_ok_handler
end
end
end
#==============================================================================
# ■ Scene_Name
#==============================================================================
class Scene_Name < Scene_MenuBase
def prepare(actor_id, max_char)
@actor_id = actor_id
@max_char = max_char
end
def start
super
@actor = $game_actors[@actor_id]
@edit_window = Window_NameEdit.new(@actor, @max_char)
@input_window = Window_NameInput.new(@edit_window)
@input_window.set_handler(:ok, method(:on_input_ok))
end
def on_input_ok
prompt = @edit_window.prompt_to_letter
@actor.name = @edit_window.name.join + prompt
return_scene
end
end