Make opening prologue more image led

This commit is contained in:
2026-06-20 09:03:44 +09:00
parent ab9d8d849b
commit 641aeb6b33
2 changed files with 92 additions and 70 deletions

View File

@@ -46,21 +46,25 @@ const SETTINGS_SAVE_VERSION := 1
const OPENING_PROLOGUE_PAGES := [
{
"title": "황건의 난",
"teaser": "황건의 난으로 고을이 불타자, 조조는 난세의 첫 군령을 결심한다.",
"body": "황건의 난이 일어나자 누런 머릿수건을 맨 무리가 고을을 불태우고 길을 끊었다. 젊은 조조는 무너지는 질서와 굶주린 백성을 보며 더는 관망할 수 없음을 깨달았다.",
"image": OPENING_PROLOGUE_REBELLION_PATH
},
{
"title": "맹덕의 결심",
"teaser": "분노를 삼킨 조조는 작은 군세라도 직접 세워 길을 열기로 한다.",
"body": "황건의 봉기가 고을을 삼키자 조조는 더는 조정의 명만 기다리지 않았다. 그는 작은 군세라도 직접 세워 백성이 빠져나갈 길을 열기로 했다.",
"image": OPENING_PROLOGUE_RESOLVE_PATH
},
{
"title": "하후돈의 합류",
"teaser": "가문의 친척 하후돈이 창을 들고 찾아와 조조의 첫 군령에 선다.",
"body": "가문의 친척 하후돈은 먼저 창을 들고 조조의 길에 섰다. 두 사람은 큰 명성보다 무너지는 고을을 구하는 첫 군령을 함께 택했다.",
"image": OPENING_PROLOGUE_XIAHOU_DUN_PATH
},
{
"title": "영천으로",
"teaser": "영천 들판에서 조조와 하후돈은 황건적의 깃발을 마주한다.",
"body": "영천 들판에서 조조와 하후돈은 황건적의 깃발을 마주했다. 마을과 성채를 기대어 버티는 적을 꺾고, 백성이 빠져나갈 길을 열어야 한다.",
"image": OPENING_PROLOGUE_YINGCHUAN_PATH
}
@@ -147,17 +151,17 @@ const BRIEFING_TACTICAL_MARKER_MAX_COUNT := 3
const BRIEFING_FORCE_PREVIEW_ICON_SIZE := Vector2(32, 32)
const BRIEFING_FORCE_PREVIEW_MAX_ALLIES := 2
const BRIEFING_FORCE_PREVIEW_MAX_ENEMY_TYPES := 4
const TITLE_STORY_FEATURE_SIZE := Vector2(646, 180)
const TITLE_STORY_FEATURE_IMAGE_SIZE := Vector2(398, 150)
const TITLE_STORY_PREVIEW_STRIP_SIZE := Vector2(646, 108)
const TITLE_STORY_PREVIEW_CARD_SIZE := Vector2(148, 88)
const TITLE_STORY_PREVIEW_IMAGE_FRAME_SIZE := Vector2(140, 64)
const TITLE_STORY_PREVIEW_IMAGE_SIZE := Vector2(132, 56)
const TITLE_STORY_PREVIEW_LABEL_SIZE := Vector2(140, 18)
const OPENING_STORY_BEAT_CARD_SIZE := Vector2(136, 78)
const OPENING_STORY_BEAT_IMAGE_FRAME_SIZE := Vector2(126, 48)
const OPENING_STORY_BEAT_IMAGE_SIZE := Vector2(118, 40)
const OPENING_STORY_BEAT_LABEL_SIZE := Vector2(104, 18)
const TITLE_STORY_FEATURE_SIZE := Vector2(646, 196)
const TITLE_STORY_FEATURE_IMAGE_SIZE := Vector2(442, 166)
const TITLE_STORY_PREVIEW_STRIP_SIZE := Vector2(646, 116)
const TITLE_STORY_PREVIEW_CARD_SIZE := Vector2(148, 98)
const TITLE_STORY_PREVIEW_IMAGE_FRAME_SIZE := Vector2(140, 74)
const TITLE_STORY_PREVIEW_IMAGE_SIZE := Vector2(132, 66)
const TITLE_STORY_PREVIEW_LABEL_SIZE := Vector2(140, 16)
const OPENING_STORY_BEAT_CARD_SIZE := Vector2(128, 68)
const OPENING_STORY_BEAT_IMAGE_FRAME_SIZE := Vector2(118, 42)
const OPENING_STORY_BEAT_IMAGE_SIZE := Vector2(116, 34)
const OPENING_STORY_BEAT_LABEL_SIZE := Vector2(96, 18)
const COMMAND_NOTICE_ICON_SIZE := Vector2(32, 32)
const COMMAND_NOTICE_MAX_ICONS := 4
const CHAPTER_SEAL_BADGE_SIZE := Vector2(54, 54)
@@ -2301,24 +2305,24 @@ func _make_seal_cluster(height: float) -> HBoxContainer:
func _make_title_story_feature_panel() -> PanelContainer:
var page: Dictionary = OPENING_PROLOGUE_PAGES[0]
var title := str(page.get("title", "황건의 난"))
var body := str(page.get("body", ""))
var body := str(page.get("teaser", page.get("body", "")))
var image_path := str(page.get("image", ""))
var tooltip := "%s\n%s" % [title, body]
var panel := PanelContainer.new()
panel.name = "TitleStoryFeaturePanel"
panel.custom_minimum_size = TITLE_STORY_FEATURE_SIZE
panel.tooltip_text = tooltip
_apply_panel_style(panel, "hud_info")
_apply_panel_style(panel, "transparent_overlay")
var row := HBoxContainer.new()
row.custom_minimum_size = Vector2(616, 158)
row.add_theme_constant_override("separation", 12)
row.custom_minimum_size = Vector2(636, 176)
row.add_theme_constant_override("separation", 10)
row.tooltip_text = tooltip
panel.add_child(row)
var image_stack := PanelContainer.new()
image_stack.name = "TitleStoryFeatureImageFrame"
image_stack.custom_minimum_size = Vector2(410, 158)
image_stack.custom_minimum_size = Vector2(462, 176)
image_stack.tooltip_text = tooltip
_apply_panel_style(image_stack, "caption")
row.add_child(image_stack)
@@ -2334,14 +2338,14 @@ func _make_title_story_feature_panel() -> PanelContainer:
image_stack.add_child(image)
var text_column := VBoxContainer.new()
text_column.custom_minimum_size = Vector2(194, 158)
text_column.custom_minimum_size = Vector2(164, 176)
text_column.size_flags_horizontal = Control.SIZE_EXPAND_FILL
text_column.add_theme_constant_override("separation", 6)
text_column.add_theme_constant_override("separation", 5)
text_column.tooltip_text = tooltip
row.add_child(text_column)
var title_row := HBoxContainer.new()
title_row.custom_minimum_size = Vector2(194, 30)
title_row.custom_minimum_size = Vector2(164, 30)
title_row.add_theme_constant_override("separation", 6)
title_row.tooltip_text = tooltip
text_column.add_child(title_row)
@@ -2350,7 +2354,7 @@ func _make_title_story_feature_panel() -> PanelContainer:
var title_label := Label.new()
title_label.name = "TitleStoryFeatureTitle"
title_label.text = title
title_label.custom_minimum_size = Vector2(158, 30)
title_label.custom_minimum_size = Vector2(130, 30)
title_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
title_label.tooltip_text = tooltip
_apply_label_style(title_label, UI_PARCHMENT_TEXT, 18)
@@ -2359,10 +2363,10 @@ func _make_title_story_feature_panel() -> PanelContainer:
var body_label := Label.new()
body_label.name = "TitleStoryFeatureBody"
body_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
body_label.custom_minimum_size = Vector2(194, 116)
body_label.custom_minimum_size = Vector2(164, 122)
body_label.tooltip_text = tooltip
_apply_label_style(body_label, UI_AGED_INK, 13)
_set_fitted_label_text(body_label, body, 13, 10, body_label.custom_minimum_size)
_apply_label_style(body_label, UI_AGED_INK, 12)
_set_fitted_label_text(body_label, body, 12, 10, body_label.custom_minimum_size)
text_column.add_child(body_label)
_set_control_tree_tooltip(panel, tooltip)
@@ -2373,10 +2377,10 @@ func _make_title_story_preview_strip() -> PanelContainer:
var panel := PanelContainer.new()
panel.name = "TitleStoryPreviewStrip"
panel.custom_minimum_size = TITLE_STORY_PREVIEW_STRIP_SIZE
_apply_panel_style(panel, "hud_info")
_apply_panel_style(panel, "transparent_overlay")
var row := HBoxContainer.new()
row.custom_minimum_size = Vector2(616, 88)
row.custom_minimum_size = Vector2(616, 98)
row.add_theme_constant_override("separation", 8)
panel.add_child(row)
@@ -2400,7 +2404,7 @@ func _make_title_story_preview_card(title: String, image_path: String, index: in
card_style.content_margin_bottom = 3
var column := VBoxContainer.new()
column.custom_minimum_size = Vector2(140, 80)
column.custom_minimum_size = Vector2(140, 90)
column.add_theme_constant_override("separation", 2)
column.tooltip_text = card.tooltip_text
card.add_child(column)
@@ -2435,7 +2439,7 @@ func _make_title_story_preview_card(title: String, image_path: String, index: in
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
label.tooltip_text = card.tooltip_text
_apply_label_style(label, UI_OLD_BRONZE, 10)
_apply_label_style(label, UI_OLD_BRONZE, 9)
column.add_child(label)
return card
@@ -2443,14 +2447,15 @@ func _make_title_story_preview_card(title: String, image_path: String, index: in
func _make_opening_story_beat_strip() -> PanelContainer:
var panel := PanelContainer.new()
panel.name = "OpeningStoryBeatStrip"
panel.position = Vector2(604, 28)
panel.size = Vector2(620, 98)
panel.custom_minimum_size = Vector2(620, 98)
_apply_panel_style(panel, "hud_info")
panel.position = Vector2(650, 24)
panel.size = Vector2(560, 82)
panel.custom_minimum_size = Vector2(560, 82)
panel.modulate = Color(1.0, 1.0, 1.0, 0.90)
_apply_panel_style(panel, "transparent_overlay")
opening_prologue_story_strip = HBoxContainer.new()
opening_prologue_story_strip.name = "OpeningStoryBeatRow"
opening_prologue_story_strip.custom_minimum_size = Vector2(588, 78)
opening_prologue_story_strip.custom_minimum_size = Vector2(536, 68)
opening_prologue_story_strip.add_theme_constant_override("separation", 8)
panel.add_child(opening_prologue_story_strip)
return panel
@@ -2486,13 +2491,13 @@ func _make_opening_story_beat_card(page: Dictionary, index: int, is_current: boo
card.modulate = Color(1.0, 1.0, 1.0, 1.0) if is_current else Color(0.56, 0.55, 0.50, 0.88)
var column := VBoxContainer.new()
column.custom_minimum_size = Vector2(126, 69)
column.custom_minimum_size = Vector2(118, 60)
column.add_theme_constant_override("separation", 3)
column.tooltip_text = tooltip
card.add_child(column)
var title_row := HBoxContainer.new()
title_row.custom_minimum_size = Vector2(126, 18)
title_row.custom_minimum_size = Vector2(118, 18)
title_row.add_theme_constant_override("separation", 4)
title_row.tooltip_text = tooltip
column.add_child(title_row)
@@ -3555,25 +3560,25 @@ func _create_hud() -> void:
var opening_top_dim := ColorRect.new()
opening_top_dim.name = "OpeningTopInkShade"
opening_top_dim.color = Color(0.020, 0.017, 0.014, 0.18)
opening_top_dim.color = Color(0.020, 0.017, 0.014, 0.13)
opening_top_dim.mouse_filter = Control.MOUSE_FILTER_IGNORE
opening_top_dim.position = Vector2(0, 0)
opening_top_dim.size = Vector2(1280, 122)
opening_top_dim.size = Vector2(1280, 92)
opening_prologue_root.add_child(opening_top_dim)
var opening_bottom_dim := ColorRect.new()
opening_bottom_dim.name = "OpeningBottomInkShade"
opening_bottom_dim.color = Color(0.020, 0.018, 0.015, 0.50)
opening_bottom_dim.color = Color(0.020, 0.018, 0.015, 0.40)
opening_bottom_dim.mouse_filter = Control.MOUSE_FILTER_IGNORE
opening_bottom_dim.position = Vector2(0, 488)
opening_bottom_dim.size = Vector2(1280, 232)
opening_bottom_dim.position = Vector2(0, 532)
opening_bottom_dim.size = Vector2(1280, 188)
opening_prologue_root.add_child(opening_bottom_dim)
var opening_chapter_panel := PanelContainer.new()
opening_chapter_panel.name = "OpeningChapterSeal"
opening_chapter_panel.position = Vector2(56, 36)
opening_chapter_panel.size = Vector2(278, 58)
opening_chapter_panel.custom_minimum_size = Vector2(278, 58)
opening_chapter_panel.position = Vector2(48, 24)
opening_chapter_panel.size = Vector2(260, 52)
opening_chapter_panel.custom_minimum_size = Vector2(260, 52)
_apply_panel_style(opening_chapter_panel, "caption")
opening_prologue_root.add_child(opening_chapter_panel)
@@ -3581,68 +3586,68 @@ func _create_hud() -> void:
opening_chapter_label.text = "제1장 영천으로"
opening_chapter_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
opening_chapter_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_apply_label_style(opening_chapter_label, UI_PARCHMENT_TEXT, 21)
_apply_label_style(opening_chapter_label, UI_PARCHMENT_TEXT, 19)
opening_chapter_panel.add_child(opening_chapter_label)
opening_prologue_root.add_child(_make_opening_story_beat_strip())
var opening_caption_panel := PanelContainer.new()
opening_caption_panel.name = "OpeningCaptionScroll"
opening_caption_panel.position = Vector2(64, 508)
opening_caption_panel.size = Vector2(1152, 148)
opening_caption_panel.custom_minimum_size = Vector2(1152, 148)
opening_caption_panel.position = Vector2(64, 548)
opening_caption_panel.size = Vector2(1152, 112)
opening_caption_panel.custom_minimum_size = Vector2(1152, 112)
opening_caption_panel.modulate = Color(0.96, 0.95, 0.91, 0.99)
_apply_panel_style(opening_caption_panel, "story_caption")
opening_prologue_root.add_child(opening_caption_panel)
var opening_caption_row := HBoxContainer.new()
opening_caption_row.custom_minimum_size = Vector2(1100, 102)
opening_caption_row.add_theme_constant_override("separation", 18)
opening_caption_row.custom_minimum_size = Vector2(1100, 72)
opening_caption_row.add_theme_constant_override("separation", 16)
opening_caption_panel.add_child(opening_caption_row)
var opening_title_column := VBoxContainer.new()
opening_title_column.custom_minimum_size = Vector2(226, 102)
opening_title_column.custom_minimum_size = Vector2(214, 72)
opening_title_column.add_theme_constant_override("separation", 4)
opening_caption_row.add_child(opening_title_column)
opening_title_column.add_child(_make_seal_ribbon(226, 12))
opening_title_column.add_child(_make_seal_ribbon(214, 10))
opening_prologue_title_label = Label.new()
opening_prologue_title_label.custom_minimum_size = Vector2(226, 48)
opening_prologue_title_label.custom_minimum_size = Vector2(214, 32)
opening_prologue_title_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
opening_prologue_title_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_apply_label_style(opening_prologue_title_label, UI_AGED_INK, 25)
_apply_label_style(opening_prologue_title_label, UI_AGED_INK, 22)
opening_title_column.add_child(opening_prologue_title_label)
opening_prologue_step_label = Label.new()
opening_prologue_step_label.custom_minimum_size = Vector2(226, 20)
opening_prologue_step_label.custom_minimum_size = Vector2(214, 18)
opening_prologue_step_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
opening_prologue_step_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_apply_label_style(opening_prologue_step_label, UI_TARNISHED_BRONZE, 14)
opening_title_column.add_child(opening_prologue_step_label)
opening_prologue_body_label = Label.new()
opening_prologue_body_label.custom_minimum_size = Vector2(664, 102)
opening_prologue_body_label.custom_minimum_size = Vector2(700, 72)
opening_prologue_body_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
opening_prologue_body_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_apply_label_style(opening_prologue_body_label, UI_AGED_INK, 18)
_apply_label_style(opening_prologue_body_label, UI_AGED_INK, 17)
opening_caption_row.add_child(opening_prologue_body_label)
var opening_button_column := VBoxContainer.new()
opening_button_column.custom_minimum_size = Vector2(168, 102)
opening_button_column.add_theme_constant_override("separation", 6)
opening_button_column.custom_minimum_size = Vector2(150, 72)
opening_button_column.add_theme_constant_override("separation", 4)
opening_caption_row.add_child(opening_button_column)
opening_prologue_skip_button = Button.new()
opening_prologue_skip_button.text = "건너뛰기"
opening_prologue_skip_button.icon = _make_toolbar_icon("cancel")
opening_prologue_skip_button.custom_minimum_size = Vector2(168, 34)
opening_prologue_skip_button.custom_minimum_size = Vector2(150, 30)
opening_prologue_skip_button.tooltip_text = "오프닝을 닫고 군막으로 이동합니다."
opening_prologue_skip_button.pressed.connect(_on_opening_prologue_skip_pressed)
opening_prologue_next_button = Button.new()
opening_prologue_next_button.text = "다음"
opening_prologue_next_button.icon = _make_toolbar_icon("move")
opening_prologue_next_button.custom_minimum_size = Vector2(168, 44)
opening_prologue_next_button.custom_minimum_size = Vector2(150, 38)
opening_prologue_next_button.tooltip_text = "다음 이야기로 넘깁니다."
opening_prologue_next_button.pressed.connect(_on_opening_prologue_next_pressed)
opening_button_column.add_child(opening_prologue_next_button)
@@ -4306,14 +4311,14 @@ func _create_hud() -> void:
title_column.add_child(_make_title_story_preview_strip())
var title_body_panel := PanelContainer.new()
title_body_panel.custom_minimum_size = Vector2(646, 284)
title_body_panel.custom_minimum_size = Vector2(646, 246)
_apply_panel_style(title_body_panel, "command_seal")
title_column.add_child(title_body_panel)
var title_body_row := HBoxContainer.new()
title_body_row.add_theme_constant_override("separation", 10)
title_body_panel.add_child(title_body_row)
title_body_row.add_child(_make_edict_marker_stack(["", "", ""], 260))
title_body_row.add_child(_make_edict_marker_stack(["", "", ""], 222))
var title_menu_column := VBoxContainer.new()
title_menu_column.add_theme_constant_override("separation", 10)
@@ -4544,7 +4549,7 @@ func _create_hud() -> void:
title_settings_back_button.pressed.connect(_on_title_settings_back_pressed)
title_menu_column.add_child(title_settings_back_button)
title_body_row.add_child(_make_edict_marker_stack(["", "", ""], 260))
title_body_row.add_child(_make_edict_marker_stack(["", "", ""], 222))
title_column.add_child(_make_scroll_rod(646, 4))
for hud_button in [
@@ -13195,15 +13200,15 @@ func _update_opening_prologue_page() -> void:
_set_fitted_label_text(
opening_prologue_title_label,
str(page.get("title", "")),
25,
21,
22,
18,
opening_prologue_title_label.custom_minimum_size
)
if opening_prologue_body_label != null:
_set_fitted_label_text(
opening_prologue_body_label,
str(page.get("body", "")),
18,
17,
14,
opening_prologue_body_label.custom_minimum_size
)