diff --git a/data/campaign/campaign.json b/data/campaign/campaign.json index acc8ea2..5971454 100644 --- a/data/campaign/campaign.json +++ b/data/campaign/campaign.json @@ -12,43 +12,43 @@ }, { "id": "northern_unification", - "title": "Northern Unification", + "title": "북방 평정", "start_scenario": "010_white_horse_relief", "end_scenario": "024_liaodong_pursuit" }, { "id": "southern_expedition", - "title": "Southern Expedition", + "title": "남정", "start_scenario": "025_xinye_advance", "end_scenario": "032_jiangling_rearguard" }, { "id": "western_frontier", - "title": "Western Frontier", + "title": "서량 변경", "start_scenario": "033_tong_pass_vanguard", "end_scenario": "041_hanzhong_settlement" }, { "id": "ruxu_and_jingzhou", - "title": "Ruxu and Jingzhou", + "title": "유수·형주 전선", "start_scenario": "042_ruxu_advance", "end_scenario": "048_jing_province_settlement" }, { "id": "wei_succession", - "title": "Wei Succession", + "title": "위왕 계승", "start_scenario": "049_luoyang_summons", "end_scenario": "051_eastern_front_alarm" }, { "id": "jianye_campaign", - "title": "Jianye Campaign", + "title": "건업 공략", "start_scenario": "052_wu_river_line", "end_scenario": "059_wu_surrender" }, { "id": "southern_settlement", - "title": "Southern Settlement", + "title": "남방 평정", "start_scenario": "060_southern_holdouts", "end_scenario": "067_outer_islands" } @@ -106,287 +106,287 @@ }, { "id": "011_yan_ford_pursuit", - "title": "Yan Ford Pursuit", + "title": "연진 추격전", "path": "res://data/scenarios/011_yan_ford_pursuit.json" }, { "id": "012_guandu_showdown", - "title": "Guandu Showdown", + "title": "관도 결전", "path": "res://data/scenarios/012_guandu_showdown.json" }, { "id": "013_wuchao_raid", - "title": "Wuchao Raid", + "title": "오소 기습전", "path": "res://data/scenarios/013_wuchao_raid.json" }, { "id": "014_cangting_pursuit", - "title": "Cangting Pursuit", + "title": "창정 추격전", "path": "res://data/scenarios/014_cangting_pursuit.json" }, { "id": "015_ye_campaign", - "title": "Ye Campaign", + "title": "업성 공략전", "path": "res://data/scenarios/015_ye_campaign.json" }, { "id": "016_ye_siege", - "title": "Ye Siege", + "title": "업성 포위전", "path": "res://data/scenarios/016_ye_siege.json" }, { "id": "017_ye_surrender", - "title": "Ye Surrender", + "title": "업성 항복전", "path": "res://data/scenarios/017_ye_surrender.json" }, { "id": "018_northern_pursuit", - "title": "Northern Pursuit", + "title": "북방 추격전", "path": "res://data/scenarios/018_northern_pursuit.json" }, { "id": "019_nanpi_pressure", - "title": "Nanpi Pressure", + "title": "남피 압박전", "path": "res://data/scenarios/019_nanpi_pressure.json" }, { "id": "020_nanpi_surrender", - "title": "Nanpi Surrender", + "title": "남피 항복전", "path": "res://data/scenarios/020_nanpi_surrender.json" }, { "id": "021_bohai_remnants", - "title": "Bohai Remnants", + "title": "발해 잔당전", "path": "res://data/scenarios/021_bohai_remnants.json" }, { "id": "022_liaoxi_pursuit", - "title": "Liaoxi Pursuit", + "title": "요서 추격전", "path": "res://data/scenarios/022_liaoxi_pursuit.json" }, { "id": "023_white_wolf_mountain", - "title": "White Wolf Mountain", + "title": "백랑산 전투", "path": "res://data/scenarios/023_white_wolf_mountain.json" }, { "id": "024_liaodong_pursuit", - "title": "Liaodong Pursuit", + "title": "요동 추격전", "path": "res://data/scenarios/024_liaodong_pursuit.json" }, { "id": "025_xinye_advance", - "title": "Xinye Advance", + "title": "신야 진격전", "path": "res://data/scenarios/025_xinye_advance.json" }, { "id": "026_changban_pursuit", - "title": "Changban Pursuit", + "title": "장판 추격전", "path": "res://data/scenarios/026_changban_pursuit.json" }, { "id": "027_jiangling_chase", - "title": "Jiangling Chase", + "title": "강릉 추격전", "path": "res://data/scenarios/027_jiangling_chase.json" }, { "id": "028_xiakou_pursuit", - "title": "Xiakou Pursuit", + "title": "하구 추격전", "path": "res://data/scenarios/028_xiakou_pursuit.json" }, { "id": "029_red_cliffs_fleet", - "title": "Red Cliffs Fleet", + "title": "적벽 수군전", "path": "res://data/scenarios/029_red_cliffs_fleet.json" }, { "id": "030_red_cliffs_fire", - "title": "Red Cliffs Fire", + "title": "적벽 화공전", "path": "res://data/scenarios/030_red_cliffs_fire.json" }, { "id": "031_huarong_retreat", - "title": "Huarong Retreat", + "title": "화용도 퇴각전", "path": "res://data/scenarios/031_huarong_retreat.json" }, { "id": "032_jiangling_rearguard", - "title": "Jiangling Rearguard", + "title": "강릉 후위전", "path": "res://data/scenarios/032_jiangling_rearguard.json" }, { "id": "033_tong_pass_vanguard", - "title": "Tong Pass Vanguard", + "title": "동관 선봉전", "path": "res://data/scenarios/033_tong_pass_vanguard.json" }, { "id": "034_ma_chao_counterstroke", - "title": "Ma Chao Counterstroke", + "title": "마초 반격전", "path": "res://data/scenarios/034_ma_chao_counterstroke.json" }, { "id": "035_weishui_camps", - "title": "Weishui Camps", + "title": "위수 진영전", "path": "res://data/scenarios/035_weishui_camps.json" }, { "id": "036_weishui_crossing", - "title": "Weishui Crossing", + "title": "위수 도하전", "path": "res://data/scenarios/036_weishui_crossing.json" }, { "id": "037_guanzhong_foothold", - "title": "Guanzhong Foothold", + "title": "관중 교두보전", "path": "res://data/scenarios/037_guanzhong_foothold.json" }, { "id": "038_ma_chao_retreat", - "title": "Ma Chao Retreat", + "title": "마초 퇴각전", "path": "res://data/scenarios/038_ma_chao_retreat.json" }, { "id": "039_hanzhong_approach", - "title": "Hanzhong Approach", + "title": "한중 접근전", "path": "res://data/scenarios/039_hanzhong_approach.json" }, { "id": "040_hanzhong_gate", - "title": "Hanzhong Gate", + "title": "한중 관문전", "path": "res://data/scenarios/040_hanzhong_gate.json" }, { "id": "041_hanzhong_settlement", - "title": "Hanzhong Settlement", + "title": "한중 평정전", "path": "res://data/scenarios/041_hanzhong_settlement.json" }, { "id": "042_ruxu_advance", - "title": "Ruxu Advance", + "title": "유수 진격전", "path": "res://data/scenarios/042_ruxu_advance.json" }, { "id": "043_ruxu_river_line", - "title": "Ruxu River Line", + "title": "유수 수로전", "path": "res://data/scenarios/043_ruxu_river_line.json" }, { "id": "044_ruxu_crossing", - "title": "Ruxu Crossing", + "title": "유수 도하전", "path": "res://data/scenarios/044_ruxu_crossing.json" }, { "id": "045_fancheng_relief", - "title": "Fancheng Relief", + "title": "번성 구원전", "path": "res://data/scenarios/045_fancheng_relief.json" }, { "id": "046_jingzhou_supply_line", - "title": "Jingzhou Supply Line", + "title": "형주 보급로전", "path": "res://data/scenarios/046_jingzhou_supply_line.json" }, { "id": "047_maicheng_pursuit", - "title": "Maicheng Pursuit", + "title": "맥성 추격전", "path": "res://data/scenarios/047_maicheng_pursuit.json" }, { "id": "048_jing_province_settlement", - "title": "Jing Province Settlement", + "title": "형주 평정전", "path": "res://data/scenarios/048_jing_province_settlement.json" }, { "id": "049_luoyang_summons", - "title": "Luoyang Summons", + "title": "낙양 소환전", "path": "res://data/scenarios/049_luoyang_summons.json" }, { "id": "050_wei_succession", - "title": "Wei Succession", + "title": "위왕 계승전", "path": "res://data/scenarios/050_wei_succession.json" }, { "id": "051_eastern_front_alarm", - "title": "Eastern Front Alarm", + "title": "동부 전선 경보", "path": "res://data/scenarios/051_eastern_front_alarm.json" }, { "id": "052_wu_river_line", - "title": "Wu River Line", + "title": "오나라 수로전", "path": "res://data/scenarios/052_wu_river_line.json" }, { "id": "053_jianye_approach", - "title": "Jianye Approach", + "title": "건업 진격전", "path": "res://data/scenarios/053_jianye_approach.json" }, { "id": "054_wu_counterstroke", - "title": "Wu Counterstroke", + "title": "오군 반격전", "path": "res://data/scenarios/054_wu_counterstroke.json" }, { "id": "055_jianye_gate", - "title": "Jianye Gate", + "title": "건업 성문전", "path": "res://data/scenarios/055_jianye_gate.json" }, { "id": "056_jianye_sortie", - "title": "Jianye Sortie", + "title": "건업 출격전", "path": "res://data/scenarios/056_jianye_sortie.json" }, { "id": "057_inner_jianye", - "title": "Inner Jianye", + "title": "건업 내성전", "path": "res://data/scenarios/057_inner_jianye.json" }, { "id": "058_jianye_command", - "title": "Jianye Command", + "title": "건업 지휘부전", "path": "res://data/scenarios/058_jianye_command.json" }, { "id": "059_wu_surrender", - "title": "Wu Surrender", + "title": "오나라 항복전", "path": "res://data/scenarios/059_wu_surrender.json" }, { "id": "060_southern_holdouts", - "title": "Southern Holdouts", + "title": "남방 잔당전", "path": "res://data/scenarios/060_southern_holdouts.json" }, { "id": "061_nanhai_route", - "title": "Nanhai Route", + "title": "남해 항로전", "path": "res://data/scenarios/061_nanhai_route.json" }, { "id": "062_southern_fleet", - "title": "Southern Fleet", + "title": "남방 함대전", "path": "res://data/scenarios/062_southern_fleet.json" }, { "id": "063_hainan_coast", - "title": "Hainan Coast", + "title": "해남 해안전", "path": "res://data/scenarios/063_hainan_coast.json" }, { "id": "064_final_harbor", - "title": "Final Harbor", + "title": "마지막 항구전", "path": "res://data/scenarios/064_final_harbor.json" }, { "id": "065_last_captains", - "title": "Last Captains", + "title": "최후 장수전", "path": "res://data/scenarios/065_last_captains.json" }, { "id": "066_sea_exiles", - "title": "Sea Exiles", + "title": "해상 망명전", "path": "res://data/scenarios/066_sea_exiles.json" }, { "id": "067_outer_islands", - "title": "Outer Islands", + "title": "외도 평정전", "path": "res://data/scenarios/067_outer_islands.json" } ] diff --git a/data/defs/classes.json b/data/defs/classes.json index c81c6d4..e4f6f26 100644 --- a/data/defs/classes.json +++ b/data/defs/classes.json @@ -1,6 +1,6 @@ { "hero": { - "name": "Hero", + "name": "영걸", "sprite": "res://art/units/strategist.png", "tier": 1, "move_type": "foot", @@ -17,7 +17,7 @@ "promotion": { "level": 15, "to": "commander" } }, "commander": { - "name": "Commander", + "name": "도독", "sprite": "res://art/units/strategist.png", "enemy_sprite": "res://art/units/enemies/enemy_strategist.png", "tier": 2, @@ -34,7 +34,7 @@ } }, "cavalry": { - "name": "Cavalry", + "name": "기병", "sprite": "res://art/units/cavalry.png", "enemy_sprite": "res://art/units/enemies/enemy_cavalry.png", "tier": 1, @@ -52,7 +52,7 @@ "promotion": { "level": 15, "to": "elite_cavalry" } }, "elite_cavalry": { - "name": "Elite Cavalry", + "name": "정예기병", "sprite": "res://art/units/cavalry.png", "enemy_sprite": "res://art/units/enemies/enemy_cavalry.png", "tier": 2, @@ -69,7 +69,7 @@ } }, "infantry": { - "name": "Infantry", + "name": "보병", "sprite": "res://art/units/infantry.png", "enemy_sprite": "res://art/units/enemies/enemy_infantry.png", "tier": 1, @@ -87,7 +87,7 @@ "promotion": { "level": 15, "to": "guard_captain" } }, "guard_captain": { - "name": "Guard Captain", + "name": "호위장", "sprite": "res://art/units/infantry.png", "enemy_sprite": "res://art/units/enemies/enemy_infantry.png", "tier": 2, @@ -104,7 +104,7 @@ } }, "warrior": { - "name": "Warrior", + "name": "무인", "sprite": "res://art/units/warrior.png", "enemy_sprite": "res://art/units/enemies/enemy_warrior.png", "tier": 1, @@ -122,7 +122,7 @@ "promotion": { "level": 15, "to": "champion" } }, "champion": { - "name": "Champion", + "name": "맹장", "sprite": "res://art/units/warrior.png", "enemy_sprite": "res://art/units/enemies/enemy_warrior.png", "tier": 2, @@ -139,7 +139,7 @@ } }, "archer": { - "name": "Archer", + "name": "궁병", "sprite": "res://art/units/archer.png", "enemy_sprite": "res://art/units/enemies/enemy_archer.png", "tier": 1, @@ -157,7 +157,7 @@ "promotion": { "level": 15, "to": "marksman" } }, "marksman": { - "name": "Marksman", + "name": "강궁병", "sprite": "res://art/units/archer.png", "enemy_sprite": "res://art/units/enemies/enemy_archer.png", "tier": 2, @@ -174,7 +174,7 @@ } }, "strategist": { - "name": "Strategist", + "name": "책사", "sprite": "res://art/units/strategist.png", "enemy_sprite": "res://art/units/enemies/enemy_strategist.png", "tier": 1, @@ -192,7 +192,7 @@ "promotion": { "level": 15, "to": "military_advisor" } }, "military_advisor": { - "name": "Military Advisor", + "name": "군사", "sprite": "res://art/units/strategist.png", "enemy_sprite": "res://art/units/enemies/enemy_strategist.png", "tier": 2, @@ -209,7 +209,7 @@ } }, "bandit": { - "name": "Bandit", + "name": "산적", "sprite": "res://art/units/warrior.png", "enemy_sprite": "res://art/units/enemies/enemy_warrior.png", "tier": 1, diff --git a/data/defs/items.json b/data/defs/items.json index 094bfbb..0cba1a9 100644 --- a/data/defs/items.json +++ b/data/defs/items.json @@ -1,6 +1,6 @@ { "bronze_sword": { - "name": "Bronze Sword", + "name": "청동검", "kind": "weapon", "icon": "res://art/items/sword.png", "weapon_type": "sword", @@ -10,7 +10,7 @@ "price": 300 }, "iron_sword": { - "name": "Iron Sword", + "name": "철검", "kind": "weapon", "icon": "res://art/items/sword.png", "weapon_type": "sword", @@ -20,7 +20,7 @@ "price": 520 }, "training_spear": { - "name": "Training Spear", + "name": "연습창", "kind": "weapon", "icon": "res://art/items/spear.png", "weapon_type": "spear", @@ -32,7 +32,7 @@ "price": 360 }, "short_bow": { - "name": "Short Bow", + "name": "단궁", "kind": "weapon", "icon": "res://art/items/bow.png", "weapon_type": "bow", @@ -44,7 +44,7 @@ "price": 320 }, "hand_axe": { - "name": "Hand Axe", + "name": "손도끼", "kind": "weapon", "icon": "res://art/items/axe.png", "weapon_type": "axe", @@ -56,7 +56,7 @@ "price": 340 }, "war_axe": { - "name": "War Axe", + "name": "전부", "kind": "weapon", "icon": "res://art/items/axe.png", "weapon_type": "axe", @@ -68,7 +68,7 @@ "price": 680 }, "cloth_robe": { - "name": "Cloth Robe", + "name": "포의", "kind": "armor", "icon": "res://art/items/armor.png", "armor_type": "robe", @@ -77,7 +77,7 @@ "price": 120 }, "leather_armor": { - "name": "Leather Armor", + "name": "피갑", "kind": "armor", "icon": "res://art/items/armor.png", "armor_type": "light_armor", @@ -86,7 +86,7 @@ "price": 180 }, "iron_armor": { - "name": "Iron Armor", + "name": "철갑", "kind": "armor", "icon": "res://art/items/armor.png", "armor_type": "heavy_armor", @@ -95,7 +95,7 @@ "price": 520 }, "war_drum": { - "name": "War Drum", + "name": "전고", "kind": "accessory", "icon": "res://art/items/war_drum.png", "accessory_type": "accessory", @@ -104,7 +104,7 @@ "price": 640 }, "imperial_seal": { - "name": "Imperial Seal", + "name": "옥새", "kind": "accessory", "icon": "res://art/items/imperial_seal.png", "accessory_type": "accessory", @@ -113,7 +113,7 @@ "price": 900 }, "yitian_sword": { - "name": "Yitian Sword", + "name": "의천검", "kind": "weapon", "rarity": "named", "icon": "res://art/items/sword.png", @@ -126,7 +126,7 @@ "price": 1300 }, "dragon_spear": { - "name": "Dragon Spear", + "name": "용담창", "kind": "weapon", "rarity": "named", "icon": "res://art/items/spear.png", @@ -139,7 +139,7 @@ "price": 1400 }, "wind_chaser_bow": { - "name": "Wind Chaser Bow", + "name": "추풍궁", "kind": "weapon", "rarity": "named", "icon": "res://art/items/bow.png", @@ -152,7 +152,7 @@ "price": 1200 }, "black_tortoise_robe": { - "name": "Black Tortoise Robe", + "name": "현무도포", "kind": "armor", "rarity": "named", "icon": "res://art/items/armor.png", @@ -162,7 +162,7 @@ "price": 1100 }, "bean": { - "name": "Bean", + "name": "콩", "kind": "consumable", "icon": "res://art/items/panacea.png", "uses": 1, @@ -170,7 +170,7 @@ "price": 50 }, "antidote": { - "name": "Antidote", + "name": "해독약", "kind": "consumable", "icon": "res://art/items/panacea.png", "target": "ally", @@ -180,7 +180,7 @@ "price": 70 }, "panacea": { - "name": "Panacea", + "name": "만능약", "kind": "consumable", "icon": "res://art/items/panacea.png", "target": "ally", @@ -196,7 +196,7 @@ "price": 140 }, "wine": { - "name": "Wine", + "name": "술", "kind": "consumable", "icon": "res://art/items/panacea.png", "uses": 1, diff --git a/data/defs/officers.json b/data/defs/officers.json index 16393e6..cc95bcc 100644 --- a/data/defs/officers.json +++ b/data/defs/officers.json @@ -1,6 +1,7 @@ { "cao_cao": { - "name": "Cao Cao", + "name": "조조", + "aliases": ["Cao Cao"], "faction": "wei", "class_id": "hero", "portrait": "res://art/portraits/cao_cao.png", @@ -11,7 +12,8 @@ "equipment": { "weapon": "bronze_sword", "armor": "cloth_robe", "accessory": null } }, "xiahou_dun": { - "name": "Xiahou Dun", + "name": "하후돈", + "aliases": ["Xiahou Dun"], "faction": "wei", "class_id": "cavalry", "portrait": "res://art/portraits/xiahou_dun.png", @@ -22,7 +24,8 @@ "equipment": { "weapon": "training_spear", "armor": "leather_armor", "accessory": null } }, "xiahou_yuan": { - "name": "Xiahou Yuan", + "name": "하후연", + "aliases": ["Xiahou Yuan"], "faction": "wei", "class_id": "archer", "portrait": "res://art/portraits/xiahou_yuan.png", @@ -33,7 +36,8 @@ "equipment": { "weapon": "short_bow", "armor": "leather_armor", "accessory": null } }, "cao_ren": { - "name": "Cao Ren", + "name": "조인", + "aliases": ["Cao Ren"], "faction": "wei", "class_id": "infantry", "portrait": "res://art/portraits/cao_ren.png", @@ -44,7 +48,8 @@ "equipment": { "weapon": "bronze_sword", "armor": "leather_armor", "accessory": null } }, "dian_wei": { - "name": "Dian Wei", + "name": "전위", + "aliases": ["Dian Wei"], "faction": "wei", "class_id": "warrior", "portrait": "res://art/portraits/dian_wei.png", @@ -55,7 +60,8 @@ "equipment": { "weapon": "hand_axe", "armor": "leather_armor", "accessory": null } }, "guo_jia": { - "name": "Guo Jia", + "name": "곽가", + "aliases": ["Guo Jia"], "faction": "wei", "class_id": "strategist", "portrait": "res://art/portraits/guo_jia.png", @@ -66,7 +72,8 @@ "equipment": { "weapon": "bronze_sword", "armor": "cloth_robe", "accessory": null } }, "zhang_he": { - "name": "Zhang He", + "name": "장합", + "aliases": ["Zhang He"], "faction": "wei", "class_id": "elite_cavalry", "portrait": "res://art/portraits/zhang_he.png", diff --git a/data/defs/skills.json b/data/defs/skills.json index 66f1a59..a61bf91 100644 --- a/data/defs/skills.json +++ b/data/defs/skills.json @@ -1,6 +1,6 @@ { "spark": { - "name": "Spark", + "name": "섬뢰", "kind": "damage", "target": "enemy", "mp_cost": 2, @@ -9,7 +9,7 @@ "stat": "int" }, "fire_tactic": { - "name": "Fire", + "name": "화계", "kind": "damage", "target": "enemy", "mp_cost": 4, @@ -18,7 +18,7 @@ "stat": "int" }, "blaze": { - "name": "Blaze", + "name": "염진", "kind": "damage", "target": "enemy", "mp_cost": 7, @@ -29,7 +29,7 @@ "stat": "int" }, "mend": { - "name": "Mend", + "name": "소치", "kind": "heal", "target": "ally", "mp_cost": 4, @@ -38,7 +38,7 @@ "stat": "int" }, "great_mend": { - "name": "Great Mend", + "name": "대치", "kind": "heal", "target": "ally", "mp_cost": 7, @@ -49,7 +49,7 @@ "stat": "int" }, "guard_order": { - "name": "Guard Order", + "name": "수비령", "kind": "support", "target": "ally", "mp_cost": 5, @@ -61,7 +61,7 @@ ] }, "rally_order": { - "name": "Rally Order", + "name": "분기령", "kind": "support", "target": "ally", "mp_cost": 5, @@ -73,7 +73,7 @@ ] }, "march_order": { - "name": "March Order", + "name": "행군령", "kind": "support", "target": "ally", "mp_cost": 5, @@ -85,7 +85,7 @@ ] }, "focus_order": { - "name": "Focus Order", + "name": "집중령", "kind": "support", "target": "ally", "mp_cost": 4, @@ -97,7 +97,7 @@ ] }, "disrupt_order": { - "name": "Disrupt Order", + "name": "혼란령", "kind": "support", "target": "enemy", "mp_cost": 5, @@ -109,7 +109,7 @@ ] }, "hamper_order": { - "name": "Hamper Order", + "name": "둔족령", "kind": "support", "target": "enemy", "mp_cost": 5, @@ -121,7 +121,7 @@ ] }, "feint_order": { - "name": "Feint Order", + "name": "허실령", "kind": "support", "target": "enemy", "mp_cost": 4, @@ -133,7 +133,7 @@ ] }, "disarm_tactic": { - "name": "Disarm Tactic", + "name": "탈병계", "kind": "support", "target": "enemy", "mp_cost": 5, @@ -145,7 +145,7 @@ ] }, "poison_mist": { - "name": "Poison Mist", + "name": "독무", "kind": "support", "target": "enemy", "mp_cost": 6, @@ -159,7 +159,7 @@ ] }, "seal_tactic": { - "name": "Seal Tactic", + "name": "봉책계", "kind": "support", "target": "enemy", "mp_cost": 6, @@ -171,7 +171,7 @@ ] }, "snare_tactic": { - "name": "Snare Tactic", + "name": "족쇄계", "kind": "support", "target": "enemy", "mp_cost": 5, diff --git a/data/defs/terrain.json b/data/defs/terrain.json index f01c465..46ff5ae 100644 --- a/data/defs/terrain.json +++ b/data/defs/terrain.json @@ -1,7 +1,7 @@ { "G": { "id": "plain", - "name": "Plain", + "name": "평원", "color": "#6d9e4f", "defense": 0, "avoid": 0, @@ -9,7 +9,7 @@ }, "F": { "id": "forest", - "name": "Forest", + "name": "숲", "color": "#33733a", "defense": 2, "avoid": 10, @@ -17,7 +17,7 @@ }, "H": { "id": "hill", - "name": "Hill", + "name": "산지", "color": "#8c8057", "defense": 1, "avoid": 5, @@ -25,7 +25,7 @@ }, "R": { "id": "road", - "name": "Road", + "name": "관도", "color": "#a38c6b", "defense": 0, "avoid": 0, @@ -33,7 +33,7 @@ }, "W": { "id": "water", - "name": "Water", + "name": "하천", "color": "#2e5c9e", "defense": 0, "avoid": 0, @@ -41,7 +41,7 @@ }, "C": { "id": "castle", - "name": "Castle", + "name": "성채", "color": "#7f7a70", "defense": 3, "avoid": 0, diff --git a/scripts/core/battle_state.gd b/scripts/core/battle_state.gd index 181e430..78474a6 100644 --- a/scripts/core/battle_state.gd +++ b/scripts/core/battle_state.gd @@ -46,35 +46,35 @@ const GROWTH_GRADE_GAINS := { const DEFAULT_TERRAIN_DEFS := { "G": { - "name": "Plain", + "name": "평원", "move_cost": 1, "defense": 0, "avoid": 0, "color": Color(0.43, 0.62, 0.31) }, "F": { - "name": "Forest", + "name": "숲", "move_cost": 2, "defense": 2, "avoid": 10, "color": Color(0.20, 0.45, 0.23) }, "H": { - "name": "Hill", + "name": "산지", "move_cost": 2, "defense": 1, "avoid": 5, "color": Color(0.55, 0.50, 0.34) }, "R": { - "name": "Road", + "name": "관도", "move_cost": 1, "defense": 0, "avoid": 0, "color": Color(0.64, 0.55, 0.42) }, "W": { - "name": "Water", + "name": "하천", "move_cost": 99, "defense": 0, "avoid": 0, @@ -114,7 +114,7 @@ var data_catalog := DataCatalogScript.new() var rng := RandomNumberGenerator.new() -func load_battle(path: String, roster_overrides := {}, inventory_overrides := {}, flag_overrides := {}, joined_officer_overrides := []) -> bool: +func load_battle(path: String, roster_overrides := {}, inventory_overrides := {}, flag_overrides := {}, joined_officer_overrides := [], display_name_override := "") -> bool: var text := FileAccess.get_file_as_string(path) if text.is_empty(): push_error("Battle file is empty or missing: %s" % path) @@ -142,7 +142,10 @@ func load_battle(path: String, roster_overrides := {}, inventory_overrides := {} campaign_joined_officers = _joined_officer_lookup(joined_officer_overrides) terrain_defs = data_catalog.get_runtime_terrain_defs(DEFAULT_TERRAIN_DEFS) _apply_battle_data(parsed, roster_overrides_snapshot) - _emit_log("Battle loaded: %s" % battle_name) + var display_name := str(display_name_override).strip_edges() + if not display_name.is_empty(): + battle_name = display_name + _emit_log("전장도 펼침: %s" % battle_name) _run_events("battle_start") _run_events("turn_start", current_team, turn_number) _notify_changed() @@ -627,11 +630,11 @@ func select_unit(unit_id: String) -> bool: if unit.get("team", "") != current_team: return false if unit.get("acted", false): - _emit_log("%s has already acted." % unit["name"]) + _emit_log("%s는 이미 군령을 마쳤다." % unit["name"]) return false selected_unit_id = unit_id - _emit_log("Selected %s." % unit["name"]) + _emit_log("%s을 지목하였다." % unit["name"]) _notify_changed() return true @@ -650,7 +653,7 @@ func try_move_selected(cell: Vector2i, defer_reach_events := false) -> bool: if unit.get("moved", false) or unit.get("acted", false): return false if _unit_has_action_lock(unit, "move"): - _emit_log("%s cannot move while snared." % unit["name"]) + _emit_log("%s는 발이 묶여 행군하지 못한다." % unit["name"]) return false if not get_movement_range(unit["id"]).has(cell): return false @@ -661,7 +664,7 @@ func try_move_selected(cell: Vector2i, defer_reach_events := false) -> bool: unit["pos"] = cell unit["moved"] = true unit_motion_requested.emit(str(unit.get("id", "")), from_cell, cell) - _emit_log("%s moved to %s." % [unit["name"], _format_cell(cell)]) + _emit_log("%s, %s으로 진군." % [unit["name"], _format_cell(cell)]) if not defer_reach_events: _run_events("unit_reaches_tile", str(unit.get("team", "")), turn_number, unit) _check_battle_status() @@ -694,7 +697,7 @@ func cancel_pending_move(unit_id: String, from_cell: Vector2i, to_cell: Vector2i unit["pos"] = from_cell unit["moved"] = false unit_motion_requested.emit(unit_id, to_cell, from_cell) - _emit_log("%s cancels movement." % unit["name"]) + _emit_log("%s의 행군을 거두었다." % unit["name"]) _notify_changed() return true @@ -709,7 +712,7 @@ func try_attack_selected(target_id: String) -> bool: if attacker.get("acted", false): return false if _unit_has_action_lock(attacker, "attack"): - _emit_log("%s cannot attack while disarmed." % attacker["name"]) + _emit_log("%s는 병장을 빼앗겨 타격하지 못한다." % attacker["name"]) return false if attacker.get("team", "") == target.get("team", ""): return false @@ -814,7 +817,7 @@ func try_use_selected_item_on_cell(item_id: String, target_cell: Vector2i) -> bo user["acted"] = true user["moved"] = true selected_unit_id = "" - _emit_log("%s 사용: %s -> %s." % [user["name"], _item_display_name(item_id), target["name"]]) + _emit_log("%s, %s을 %s에게 사용." % [user["name"], _item_display_name(item_id), target["name"]]) _check_battle_status() _notify_changed() return true @@ -1126,7 +1129,7 @@ func _resolve_skill_support(caster: Dictionary, target: Dictionary, skill_id: St "remaining_phases": max(1, int(effect.get("duration_turns", 1))) }) target["status_effects"] = status_effects - _emit_log("%s 시전 %s -> %s. %s" % [ + _emit_log("%s, %s을 펼쳐 %s에게 %s." % [ caster["name"], skill.get("name", "책략"), target["name"], @@ -1751,25 +1754,25 @@ func try_set_unit_deployed(unit_id: String, deployed: bool) -> bool: if unit.is_empty() or unit.get("team", "") != TEAM_PLAYER: return false if bool(unit.get("required_deployment", false)) and not deployed: - _emit_log("%s must deploy." % unit["name"]) + _emit_log("%s는 반드시 출진해야 한다." % unit["name"]) return false if bool(unit.get("deployed", true)) == deployed: return true if deployed: if get_deployed_player_count() >= get_deployment_max_units(): - _emit_log("Deployment limit reached.") + _emit_log("출진 명부가 이미 찼다.") return false var target_cell := _formation_cell_for_deployment(unit) if not is_inside(target_cell): - _emit_log("No open formation cell for %s." % unit["name"]) + _emit_log("%s이 설 진형 자리가 없다." % unit["name"]) return false unit["pos"] = target_cell unit["alive"] = true unit["deployed"] = true - _emit_log("%s joins the sortie." % unit["name"]) + _emit_log("%s, 출진 명부에 들었다." % unit["name"]) else: unit["deployed"] = false - _emit_log("%s moves to reserve." % unit["name"]) + _emit_log("%s, 예비대로 물러났다." % unit["name"]) _notify_changed() return true @@ -1803,7 +1806,7 @@ func try_set_prebattle_formation(unit_id: String, cell: Vector2i) -> bool: return true occupant["pos"] = unit["pos"] unit["pos"] = cell - _emit_log("%s takes formation at %s." % [unit["name"], _format_cell(cell)]) + _emit_log("%s, %s에 진형을 잡았다." % [unit["name"], _format_cell(cell)]) _notify_changed() return true @@ -1831,23 +1834,23 @@ func try_equip_item(unit_id: String, item_id: String) -> bool: if not bool(unit.get("controllable", true)): return false if unit.get("moved", false) or unit.get("acted", false): - _emit_log("%s can change equipment before moving or acting." % unit["name"]) + _emit_log("%s는 행군이나 군령 전에만 병장을 고칠 수 있다." % unit["name"]) return false var slot := _equipment_slot_for_item(item) if slot.is_empty(): return false if int(battle_inventory.get(item_id, 0)) <= 0: - _emit_log("No %s is in inventory." % item.get("name", item_id)) + _emit_log("병장고에 %s이 없다." % item.get("name", item_id)) return false if not _unit_can_equip_item(unit, item): - _emit_log("%s cannot equip %s." % [unit["name"], item.get("name", item_id)]) + _emit_log("%s는 %s을 들 수 없다." % [unit["name"], item.get("name", item_id)]) return false var equipment: Dictionary = unit.get("equipment", {}).duplicate(true) var old_item_id := _equipment_item_id_for_slot(equipment, slot) if old_item_id == item_id: - _emit_log("%s already has %s equipped." % [unit["name"], item.get("name", item_id)]) + _emit_log("%s는 이미 %s을 지녔다." % [unit["name"], item.get("name", item_id)]) return false battle_inventory[item_id] = max(0, int(battle_inventory.get(item_id, 0)) - 1) @@ -1859,7 +1862,7 @@ func try_equip_item(unit_id: String, item_id: String) -> bool: unit["equipment"] = equipment _apply_equipment_stat_delta(unit, old_item, item) _refresh_attack_range_from_equipment(unit) - _emit_log("%s equips %s." % [unit["name"], item.get("name", item_id)]) + _emit_log("%s, %s을 장착." % [unit["name"], item.get("name", item_id)]) _notify_changed() return true @@ -1873,7 +1876,7 @@ func try_unequip_item(unit_id: String, slot: String) -> bool: if not bool(unit.get("controllable", true)): return false if unit.get("moved", false) or unit.get("acted", false): - _emit_log("%s can change equipment before moving or acting." % unit["name"]) + _emit_log("%s는 행군이나 군령 전에만 병장을 고칠 수 있다." % unit["name"]) return false var normalized_slot := _normalized_equipment_slot(slot) @@ -1883,7 +1886,7 @@ func try_unequip_item(unit_id: String, slot: String) -> bool: var equipment: Dictionary = unit.get("equipment", {}).duplicate(true) var old_item_id := _equipment_item_id_for_slot(equipment, normalized_slot) if old_item_id.is_empty(): - _emit_log("%s has no %s equipped." % [unit["name"], normalized_slot]) + _emit_log("%s는 %s에 찬 병장이 없다." % [unit["name"], _equipment_slot_display_name(normalized_slot)]) return false var old_item := get_item_def(old_item_id) @@ -1896,7 +1899,7 @@ func try_unequip_item(unit_id: String, slot: String) -> bool: _apply_equipment_stat_delta(unit, old_item, {}) _refresh_attack_range_from_equipment(unit) battle_inventory[old_item_id] = int(battle_inventory.get(old_item_id, 0)) + 1 - _emit_log("%s unequips %s." % [unit["name"], old_item.get("name", old_item_id)]) + _emit_log("%s, %s을 해제." % [unit["name"], old_item.get("name", old_item_id)]) _notify_changed() return true @@ -1996,7 +1999,7 @@ func get_map_background_path() -> String: func get_terrain_name(cell: Vector2i) -> String: - return String(terrain_defs.get(get_terrain_key(cell), DEFAULT_TERRAIN_DEFS["G"]).get("name", "Plain")) + return String(terrain_defs.get(get_terrain_key(cell), DEFAULT_TERRAIN_DEFS["G"]).get("name", "평원")) func get_terrain_color(cell: Vector2i) -> Color: @@ -2105,8 +2108,8 @@ func get_status_text() -> String: return "패전" var turn_limit := get_turn_limit() if turn_limit > 0: - return "제%d턴/%d · %s" % [turn_number, turn_limit, _team_status_text(current_team)] - return "제%d턴 · %s" % [turn_number, _team_status_text(current_team)] + return "제%d군령/%d · %s" % [turn_number, turn_limit, _team_status_text(current_team)] + return "제%d군령 · %s" % [turn_number, _team_status_text(current_team)] func _team_status_text(team: String) -> String: @@ -2718,6 +2721,17 @@ func _normalized_equipment_slot(slot: String) -> String: return "" +func _equipment_slot_display_name(slot: String) -> String: + var normalized := _normalized_equipment_slot(slot) + if normalized == "weapon": + return "무기" + if normalized == "armor": + return "갑옷" + if normalized == "accessory": + return "보물" + return "병장" + + func _equipment_item_id_for_slot(equipment: Dictionary, slot: String) -> String: var item_id = equipment.get(slot, "") if item_id == null: @@ -2872,7 +2886,7 @@ func _enemy_take_action(enemy: Dictionary) -> void: enemy["pos"] = best_cell enemy["moved"] = true unit_motion_requested.emit(str(enemy.get("id", "")), from_cell, best_cell) - _emit_log("%s advances to %s." % [enemy["name"], _format_cell(best_cell)]) + _emit_log("%s, %s으로 압박." % [enemy["name"], _format_cell(best_cell)]) _run_events("unit_reaches_tile", str(enemy.get("team", "")), turn_number, enemy) if battle_status != STATUS_ACTIVE: return @@ -3292,7 +3306,7 @@ func _resolve_attack(attacker: Dictionary, target: Dictionary, is_counter := fal func _resolve_skill_damage(caster: Dictionary, target: Dictionary, skill: Dictionary) -> bool: var damage := calculate_skill_damage(caster, target, skill) target["hp"] = max(0, int(target["hp"]) - damage) - _emit_log("%s 시전 %s -> %s, %d 피해." % [ + _emit_log("%s, %s을 펼쳐 %s에게 %d 피해." % [ caster["name"], skill.get("name", "책략"), target["name"], @@ -3329,7 +3343,7 @@ func _handle_unit_defeated(unit: Dictionary) -> void: func _resolve_skill_heal(caster: Dictionary, target: Dictionary, skill: Dictionary) -> int: var healed := calculate_skill_heal(caster, target, skill) target["hp"] = min(int(target["max_hp"]), int(target["hp"]) + healed) - _emit_log("%s 시전 %s -> %s, 병력 %d 회복." % [ + _emit_log("%s, %s으로 %s의 병력 %d 회복." % [ caster["name"], skill.get("name", "책략"), target["name"], @@ -3360,8 +3374,8 @@ func _level_up(unit: Dictionary) -> void: unit["mp"] = min(int(unit["max_mp"]), int(unit.get("mp", 0)) + mp_gain) for stat in ["atk", "def", "int", "agi"]: unit[stat] = int(unit.get(stat, 0)) + _growth_gain(unit, stat, 1) - _emit_log("%s Lv.%d에 이르렀다." % [unit["name"], unit["level"]]) - _emit_combat_feedback(unit, "Lv.%d" % int(unit["level"]), "progress") + _emit_log("%s 품계 %d에 이르렀다." % [unit["name"], unit["level"]]) + _emit_combat_feedback(unit, "품계 %d" % int(unit["level"]), "progress") if str(unit.get("team", "")) == TEAM_PLAYER: _record_progression_event({ "type": "level_up", @@ -3396,8 +3410,8 @@ func _try_promote_unit(unit: Dictionary) -> void: _apply_stat_bonus_delta(unit, class_def.get("base_bonus", {}), next_class_def.get("base_bonus", {})) unit["class_id"] = next_class_id _apply_class_runtime_fields(unit, next_class_id) - _emit_log("%s promotes to %s." % [unit["name"], unit["class"]]) - _emit_combat_feedback(unit, "PROMOTE", "progress") + _emit_log("%s, %s으로 승급하였다." % [unit["name"], unit["class"]]) + _emit_combat_feedback(unit, "승급", "progress") if str(unit.get("team", "")) == TEAM_PLAYER: _record_progression_event({ "type": "promotion", @@ -4082,7 +4096,7 @@ func _grant_event_item(action: Dictionary, trigger_unit: Dictionary = {}) -> boo var count: int = maxi(1, int(action.get("count", 1))) battle_inventory[item_id] = int(battle_inventory.get(item_id, 0)) + count var item_name: String = _item_display_name(item_id) - var count_text: String = "" if count == 1 else " x%d" % count + var count_text: String = "" if count == 1 else " %d점" % count _emit_log("전리품: %s%s." % [item_name, count_text]) if not trigger_unit.is_empty() and bool(trigger_unit.get("alive", false)): _emit_combat_feedback(trigger_unit, "+%s" % item_name, "item") @@ -4097,10 +4111,10 @@ func _grant_event_gold(action: Dictionary, trigger_unit: Dictionary = {}) -> boo battle_gold_reward += amount var text := str(action.get("text", "")).strip_edges() if text.is_empty(): - text = "군자금: %dG." % amount + text = "군자금 %d냥을 거두었다." % amount _emit_log(text) if not trigger_unit.is_empty() and bool(trigger_unit.get("alive", false)): - _emit_combat_feedback(trigger_unit, "+%dG" % amount, "gold") + _emit_combat_feedback(trigger_unit, "+%d냥" % amount, "gold") return true @@ -4226,28 +4240,28 @@ func _spawn_event_deployment(deployment) -> bool: var hydrated_unit := data_catalog.hydrate_deployment(deployment) _apply_roster_overlay(hydrated_unit, roster_overrides_snapshot) if not _is_deployment_available(hydrated_unit): - _emit_log("Reinforcement %s is not available." % hydrated_unit.get("name", hydrated_unit.get("id", "unit"))) + _emit_log("원군 %s은 아직 부를 수 없다." % hydrated_unit.get("name", hydrated_unit.get("id", "unit"))) return false var unit := _prepare_unit(hydrated_unit) if unit.is_empty(): return false if not is_inside(unit["pos"]): - _emit_log("Reinforcement %s could not deploy outside the battlefield." % unit["name"]) + _emit_log("원군 %s은 전장 밖에 설 수 없다." % unit["name"]) return false if get_move_cost(unit["pos"], str(unit.get("move_type", "foot"))) >= 99: - _emit_log("Reinforcement %s could not deploy on impassable terrain." % unit["name"]) + _emit_log("원군 %s은 험지에 설 수 없다." % unit["name"]) return false if not get_unit(unit["id"]).is_empty(): - _emit_log("Reinforcement %s already exists." % unit["name"]) + _emit_log("원군 %s은 이미 전장에 있다." % unit["name"]) return false if not get_unit_at(unit["pos"]).is_empty(): - _emit_log("Reinforcement %s could not deploy at %s." % [unit["name"], _format_cell(unit["pos"])]) + _emit_log("원군 %s은 %s에 설 수 없다." % [unit["name"], _format_cell(unit["pos"])]) return false unit["acted"] = current_team == unit.get("team", "") unit["moved"] = current_team == unit.get("team", "") units.append(unit) - _emit_log("%s arrives at %s." % [unit["name"], _format_cell(unit["pos"])]) + _emit_log("%s, %s에 당도." % [unit["name"], _format_cell(unit["pos"])]) return true diff --git a/scripts/core/campaign_state.gd b/scripts/core/campaign_state.gd index 44abc08..8a5d615 100644 --- a/scripts/core/campaign_state.gd +++ b/scripts/core/campaign_state.gd @@ -840,8 +840,8 @@ func get_progress_text() -> String: var current_title := get_scenario_title(current_scenario_id) if current_title.is_empty(): current_title = get_scenario_title(get_start_scenario_id()) - var complete_text := "complete" if is_campaign_complete() else "in progress" - return "%s | %s | Gold %d | %d/%d complete" % [ + var complete_text := "전기 완결" if is_campaign_complete() else "진군 중" + return "%s · %s · 군자금 %d냥 · 봉인 %d/%d" % [ campaign_title, complete_text, gold, diff --git a/scripts/core/data_catalog.gd b/scripts/core/data_catalog.gd index 9432140..9ebada6 100644 --- a/scripts/core/data_catalog.gd +++ b/scripts/core/data_catalog.gd @@ -137,6 +137,9 @@ func get_portrait_for_speaker(speaker_name: String) -> String: var officer := _get_dict(officers, officer_id) if _normalized_speaker_name(str(officer.get("name", ""))) == normalized_speaker: return str(officer.get("portrait", "")) + for alias in officer.get("aliases", []): + if _normalized_speaker_name(str(alias)) == normalized_speaker: + return str(officer.get("portrait", "")) return "" diff --git a/scripts/scenes/battle_scene.gd b/scripts/scenes/battle_scene.gd index 8d98e41..3ab8402 100644 --- a/scripts/scenes/battle_scene.gd +++ b/scripts/scenes/battle_scene.gd @@ -1912,16 +1912,16 @@ func _play_log_sfx(message: String) -> void: elif message.contains(" attacks ") or message.contains(" counterattacks ") or message.contains(" 공격 ") or message.contains(" 반격 "): if message.contains(" for ") or message.contains("피해"): _play_sfx("hit_heavy") - elif message.contains(" casts ") or message.contains(" 시전 "): + elif message.contains(" casts ") or message.contains(" 시전 ") or message.contains("펼쳐"): if message.contains("restoring") or message.contains(" until ") or message.contains("회복") or message.contains("지원"): _play_sfx("skill_cast") else: _play_sfx("fire_skill") - elif message.contains(" moved to ") or message.contains(" advances to ") or message.contains(" takes formation at ") or message.contains(" arrives at "): + elif message.contains(" moved to ") or message.contains(" advances to ") or message.contains(" takes formation at ") or message.contains(" arrives at ") or message.contains("진군") or message.contains("진형을 잡았다") or message.contains("압박") or message.contains("당도"): _play_sfx("footstep") - elif message.contains(" uses ") or message.contains(" equips ") or message.contains(" 사용:") or message.contains(" 장착:") or message.contains(" 매입:") or message.contains(" 매각:") or message.begins_with("Received ") or message.begins_with("전리품:") or message.begins_with("군자금:"): + elif message.contains(" uses ") or message.contains(" equips ") or message.contains(" 사용:") or message.contains("장착") or message.contains("해제") or message.contains(" 매입:") or message.contains(" 매각:") or message.contains("군자금") or message.begins_with("Received ") or message.begins_with("전리품:"): _play_sfx("item_pickup") - elif message.contains(" reaches Lv.") or message.contains(" promotes to ") or message.contains("공적") or message.contains("승급"): + elif message.contains("공적") or message.contains("품계") or message.contains("승급"): _play_sfx("menu_confirm") @@ -3410,20 +3410,20 @@ func _skill_target_preview_badge_for_cell(selected: Dictionary, target: Dictiona if total_heal <= 0: return _make_target_preview_badge_at("가득", "invalid", cell) if bool(preview.get("has_area", false)): - return _make_target_preview_badge_at("+%d x%d" % [total_heal, target_count], "heal", cell) + return _make_target_preview_badge_at("+%d %d군" % [total_heal, target_count], "heal", cell) return _make_target_preview_badge_at("+%d 병력" % heal, "heal", cell) if kind == "support": var effect_text := str(preview.get("effect_text", "지원")) var badge_kind := _support_preview_badge_kind(effect_text) if bool(preview.get("has_area", false)): - return _make_target_preview_badge_at("%s x%d" % [_compact_support_preview_text(effect_text), target_count], badge_kind, cell) + return _make_target_preview_badge_at("%s %d군" % [_compact_support_preview_text(effect_text), target_count], badge_kind, cell) return _make_target_preview_badge_at(_compact_support_preview_text(effect_text), badge_kind, cell) if bool(preview.get("has_area", false)): var defeat_count := int(preview.get("defeat_count", 0)) if defeat_count > 0: - return _make_target_preview_badge_at("퇴각 x%d" % defeat_count, "damage", cell) - return _make_target_preview_badge_at("-%d x%d" % [int(preview.get("total_damage", 0)), target_count], "damage", cell) + return _make_target_preview_badge_at("퇴각 %d군" % defeat_count, "damage", cell) + return _make_target_preview_badge_at("-%d %d군" % [int(preview.get("total_damage", 0)), target_count], "damage", cell) var result_text := "퇴각" if bool(preview.get("would_defeat", false)) else "-%d" % int(preview.get("damage", 0)) return _make_target_preview_badge_at(result_text, "damage", cell) @@ -3688,7 +3688,7 @@ func _format_unit_focus_text(unit: Dictionary, prefix: String) -> String: roster_mark, control_label ]) - lines.append("%s Lv.%d %s %s" % [ + lines.append("%s 품계 %d %s %s" % [ _unit_team_text(str(unit.get("team", ""))), int(unit.get("level", 1)), _unit_class_display_name(unit), @@ -3941,7 +3941,7 @@ func _update_cell_info() -> void: var unit: Dictionary = summary["unit"] if not unit.is_empty(): var control_label := " 호위" if not bool(unit.get("controllable", true)) else "" - text += "\n군기: %s%s %s Lv.%d\n%s %s 병력 %d/%d 기력 %d/%d\n병장: %s" % [ + text += "\n군기: %s%s %s 품계 %d\n%s %s 병력 %d/%d 기력 %d/%d\n병장: %s" % [ unit["name"], control_label, _unit_team_text(str(unit["team"])), @@ -4027,7 +4027,7 @@ func _format_skill_threat_area_text(preview: Dictionary) -> String: var target_count := int(preview.get("target_count", 0)) if target_count <= 1: return "" - return " x%d" % target_count + return " %d군" % target_count func _compact_name_list(names: Array[String], limit: int) -> String: @@ -4168,7 +4168,7 @@ func _update_skill_forecast(selected: Dictionary) -> void: ] else: var defeat_count := int(preview.get("defeat_count", 0)) - var defeat_text := " 퇴각 x%d" % defeat_count if defeat_count > 0 else "" + var defeat_text := " 퇴각 %d군" % defeat_count if defeat_count > 0 else "" var total_damage := int(preview.get("total_damage", preview.get("damage", 0))) if not has_area: var single_defeat_text := " 퇴각" if bool(preview.get("would_defeat", false)) else "" @@ -4204,7 +4204,7 @@ func _update_item_forecast(selected: Dictionary) -> void: var target := state.get_unit_at(hover_cell) var range_text := "사거리 안" if preview["in_range"] else "사거리 밖" - var count_text := "x%d" % int(preview.get("count", 0)) + var count_text := "잔량 %d" % int(preview.get("count", 0)) if target.is_empty() or not preview["valid_target"]: forecast_label.text = "%s: %s, %s\n지목할 대상이 없습니다." % [ preview["item_name"], @@ -4260,7 +4260,7 @@ func _update_result_panel() -> void: result_restart_button.visible = false if next_battle_button != null: next_battle_button.visible = false - result_label.text = "%s 전기 완결\n현 병서는 모두 정리되었습니다.\n군자금 %dG\n새 전기를 열어 다시 진행합니다." % [ + result_label.text = "%s 전기 완결\n현 병서는 모두 정리되었습니다.\n군자금 %d냥\n새 전기를 열어 다시 진행합니다." % [ campaign_state.campaign_title, campaign_state.gold ] @@ -5050,14 +5050,17 @@ func _load_scenario(scenario_id: String) -> void: campaign_state.get_roster_overrides(), campaign_state.get_inventory_snapshot(), campaign_state.get_flags_snapshot(), - campaign_state.get_joined_officers_snapshot() + campaign_state.get_joined_officers_snapshot(), + campaign_state.get_scenario_title(active_scenario_id) ) func _format_briefing_title(briefing: Dictionary) -> String: - var title := str(briefing.get("title", state.battle_name)) + var title := campaign_state.get_scenario_title(active_scenario_id) if title.is_empty(): - title = campaign_state.get_scenario_title(active_scenario_id) + title = str(briefing.get("title", state.battle_name)) + if title.is_empty(): + title = state.battle_name var chapter_title := campaign_state.get_chapter_title_for_scenario(active_scenario_id) if not chapter_title.is_empty(): var chapter_position := campaign_state.get_chapter_position_for_scenario(active_scenario_id) @@ -5079,18 +5082,20 @@ func _format_briefing_location(briefing: Dictionary) -> String: var battle_text := _format_briefing_chapter_battle_text(briefing) if location.is_empty(): return battle_text - return "%s - %s" % [battle_text, location] + return "%s · %s" % [battle_text, location] if campaign_state.campaign_title.is_empty(): return location if location.is_empty(): return campaign_state.campaign_title - return "%s - %s" % [campaign_state.campaign_title, location] + return "%s · %s" % [campaign_state.campaign_title, location] func _format_briefing_chapter_battle_text(briefing: Dictionary) -> String: - var title := str(briefing.get("title", state.battle_name)) + var title := campaign_state.get_scenario_title(active_scenario_id) if title.is_empty(): - title = campaign_state.get_scenario_title(active_scenario_id) + title = str(briefing.get("title", state.battle_name)) + if title.is_empty(): + title = state.battle_name var position := campaign_state.get_scenario_position_in_chapter(active_scenario_id) var count := campaign_state.get_scenario_count_in_chapter(active_scenario_id) if position > 0 and count > 0: @@ -5750,7 +5755,7 @@ func _format_camp_conversation_effects_text(conversation: Dictionary) -> String: if item.is_empty(): continue var count := maxi(1, int(effect.get("count", 1))) - var count_text := "" if count == 1 else " x%d" % count + var count_text := "" if count == 1 else " %d점" % count parts.append("보급 %s%s" % [_item_display_name(item_id), count_text]) if parts.is_empty(): return "" @@ -5796,7 +5801,7 @@ func _format_camp_conversation_effect_claim_text(conversation: Dictionary) -> St if item_id.is_empty(): continue var count := maxi(1, int(effect.get("count", 1))) - var count_text := "" if count == 1 else " x%d" % count + var count_text := "" if count == 1 else " %d점" % count messages.append("군막 보급 수령: %s%s." % [_item_display_name(item_id), count_text]) if messages.is_empty(): return "군막 보급을 수령했습니다." @@ -5931,7 +5936,7 @@ func _format_current_checkpoint_text() -> String: var title := campaign_state.get_scenario_title(campaign_state.current_scenario_id) if title.is_empty(): title = campaign_state.get_scenario_title(campaign_state.get_start_scenario_id()) - return "현재 봉인: %s - %d/%d 봉인 - 군자금 %dG" % [ + return "현재 봉인: %s · %d/%d 봉인 · 군자금 %d냥" % [ title, campaign_state.completed_scenarios.size(), campaign_state.get_scenario_count(), @@ -5946,8 +5951,8 @@ func _format_manual_checkpoint_text() -> String: var title := str(summary.get("current_scenario_title", "")) if title.is_empty(): title = str(summary.get("current_scenario_id", "Unknown")) - var pending_suffix := " - 회의 미결" if bool(summary.get("pending_choice", false)) else "" - return "수동 봉인: %s - %d/%d 봉인 - 군자금 %dG%s" % [ + var pending_suffix := " · 회의 미결" if bool(summary.get("pending_choice", false)) else "" + return "수동 봉인: %s · %d/%d 봉인 · 군자금 %d냥%s" % [ title, int(summary.get("completed_count", 0)), int(summary.get("total_count", 0)), @@ -5961,9 +5966,9 @@ func _on_manual_save_pressed() -> void: return _play_ui_confirm() if campaign_state.save_manual_game(): - _on_log_added("Manual checkpoint saved.") + _on_log_added("수동 전기가 봉인되었다.") else: - _on_log_added("Could not save manual checkpoint.") + _on_log_added("수동 전기를 봉하지 못했다.") _rebuild_save_menu() @@ -5972,12 +5977,12 @@ func _on_manual_load_pressed() -> void: return _play_ui_confirm() if not campaign_state.load_manual_game(): - _on_log_added("Could not load manual checkpoint.") + _on_log_added("수동 봉인을 열지 못했다.") _rebuild_save_menu() return if log_box != null: log_box.clear() - log_box.append_text("Manual checkpoint loaded.\n") + log_box.append_text("수동 봉인을 열었다.\n") _reload_from_campaign_state() @@ -6074,7 +6079,7 @@ func _format_roster_unit_button_text(unit: Dictionary) -> String: var state_text := "출진" if bool(unit.get("deployed", true)) else "예비" var required_text := " 필수" if bool(unit.get("required_deployment", false)) else "" var protected_text := " 호위" if not bool(unit.get("controllable", true)) else "" - return "%s%s Lv.%d %s %s%s" % [ + return "%s%s 품계 %d %s %s%s" % [ str(unit.get("name", "장수")), protected_text, int(unit.get("level", 1)), @@ -6274,7 +6279,7 @@ func _find_unit_in_list(units: Array, unit_id: String) -> Dictionary: func _format_armory_unit_button_text(unit: Dictionary) -> String: var marker := "> " if str(unit.get("id", "")) == armory_unit_id else "" - return "%s%s Lv.%d %s" % [ + return "%s%s 품계 %d %s" % [ marker, str(unit.get("name", "장수")), int(unit.get("level", 1)), @@ -6319,10 +6324,10 @@ func _on_armory_unequip_pressed(slot: String) -> void: func _save_prebattle_equipment_change() -> bool: if campaign_state.try_save_prebattle_loadout(state.get_player_roster_snapshot(), state.get_inventory_snapshot()): - _on_log_added("Saved pre-battle equipment.") + _on_log_added("출진 병장을 고쳐 봉하였다.") return true _play_ui_cancel() - _on_log_added("Could not save pre-battle equipment.") + _on_log_added("출진 병장 기록을 봉하지 못했다.") _load_scenario(active_scenario_id) _show_briefing() return false @@ -6334,7 +6339,7 @@ func _rebuild_shop_menu() -> void: _clear_shop_list() if shop_status_label != null: var mode_text := "매각" if shop_sell_mode else "매입" - shop_status_label.text = "%s - 군자금 %dG - %s" % [ + shop_status_label.text = "%s · 군자금 %d냥 · %s" % [ mode_text, campaign_state.gold, _format_inventory_status_text() @@ -6425,7 +6430,7 @@ func _add_shop_merchant_notice() -> void: row.add_theme_constant_override("separation", 8) shop_list.add_child(row) - row.add_child(_make_initials_badge(str(merchant.get("name", "Merchant")), SHOP_MERCHANT_BADGE_SIZE, 18)) + row.add_child(_make_initials_badge(str(merchant.get("name", "야상")), SHOP_MERCHANT_BADGE_SIZE, 18)) var merchant_label := Label.new() merchant_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART @@ -6447,7 +6452,7 @@ func _format_shop_merchant_notice_text(merchant: Dictionary) -> String: if lines.is_empty(): return "" return "%s: %s" % [ - str(merchant.get("name", "Merchant")), + str(merchant.get("name", "야상")), _join_strings(lines, " ") ] @@ -6523,27 +6528,27 @@ func _make_shop_item_icon_panel(item_id: String, item: Dictionary) -> PanelConta func _format_shop_buy_action_text(item_id: String, _item: Dictionary, price: int) -> String: - return "매입 %s %dG" % [_item_display_name(item_id), price] + return "매입 %s %d냥" % [_item_display_name(item_id), price] func _format_shop_sell_action_text(item_id: String, _item: Dictionary, sale_price: int) -> String: - return "매각 %s %dG" % [_item_display_name(item_id), sale_price] + return "매각 %s %d냥" % [_item_display_name(item_id), sale_price] func _format_shop_buy_item_detail_text(_item_id: String, item: Dictionary, price: int, owned: int, stock_limit: int = -1, remaining: int = -1) -> String: var parts := _shop_item_common_detail_parts(item, owned) if stock_limit >= 0: - parts.append("재고 %d/%d" % [max(0, remaining), stock_limit]) + parts.append("잔량 %d/%d" % [max(0, remaining), stock_limit]) if stock_limit >= 0 and remaining <= 0: - parts.append("품절") + parts.append("매진") elif campaign_state.gold < price: - parts.append("부족 %dG" % (price - campaign_state.gold)) + parts.append("부족 %d냥" % (price - campaign_state.gold)) return _join_strings(parts, " · ") func _format_shop_sell_item_detail_text(_item_id: String, item: Dictionary, _sale_price: int, owned: int) -> String: var parts := _shop_item_common_detail_parts(item, owned) - parts.append("반값 매각") + parts.append("반값으로 넘김") return _join_strings(parts, " · ") @@ -6555,7 +6560,7 @@ func _shop_item_common_detail_parts(item: Dictionary, owned: int) -> Array: var kind := str(item.get("kind", "item")).capitalize() if not kind.is_empty(): parts.append(_item_kind_text(kind)) - parts.append("보유 x%d" % owned) + parts.append("보유 %d점" % owned) return parts @@ -6568,13 +6573,13 @@ func _format_shop_item_tooltip_text(primary_text: String, detail_text: String) - func _format_shop_item_button_text(item_id: String, item: Dictionary, price: int, owned: int, stock_limit: int = -1, remaining: int = -1) -> String: var unavailable := "" if stock_limit >= 0 and remaining <= 0: - unavailable = " - 품절" + unavailable = " · 매진" elif campaign_state.gold < price: - unavailable = " - 부족 %dG" % (price - campaign_state.gold) + unavailable = " · 부족 %d냥" % (price - campaign_state.gold) var stock_text := "" if stock_limit >= 0: - stock_text = " 재고 %d/%d" % [max(0, remaining), stock_limit] - return "%s %dG %s 보유 x%d%s%s" % [ + stock_text = " 잔량 %d/%d" % [max(0, remaining), stock_limit] + return "%s %d냥 %s 보유 %d점%s%s" % [ _item_display_name(item_id), price, _format_shop_item_effect_text(item), @@ -6585,7 +6590,7 @@ func _format_shop_item_button_text(item_id: String, item: Dictionary, price: int func _format_shop_sell_item_button_text(item_id: String, item: Dictionary, sale_price: int, owned: int) -> String: - return "%s 매각 %dG %s 보유 x%d" % [ + return "%s 매각 %d냥 %s 보유 %d점" % [ _item_display_name(item_id), sale_price, _format_shop_item_effect_text(item), @@ -6601,7 +6606,7 @@ func _format_shop_item_effect_text(item: Dictionary) -> String: var parts := [] var equipment_type := str(item.get("%s_type" % kind, "")) if not equipment_type.is_empty(): - parts.append(equipment_type.capitalize()) + parts.append(_equipment_type_text(equipment_type)) if item.has("range"): var range_value: Array = item.get("range", []) if range_value.size() >= 2: @@ -6614,7 +6619,7 @@ func _format_shop_item_effect_text(item: Dictionary) -> String: func _item_kind_text(kind: String) -> String: var normalized := kind.strip_edges().to_lower() if normalized == "consumable": - return "소모품" + return "소모 물자" if normalized == "weapon": return "무기" if normalized == "armor": @@ -6626,6 +6631,27 @@ func _item_kind_text(kind: String) -> String: return kind.capitalize() +func _equipment_type_text(equipment_type: String) -> String: + var normalized := equipment_type.strip_edges().to_lower() + if normalized == "sword": + return "검" + if normalized == "spear": + return "창" + if normalized == "bow": + return "궁" + if normalized == "axe": + return "부" + if normalized == "robe": + return "도포" + if normalized == "light_armor": + return "경갑" + if normalized == "heavy_armor": + return "중갑" + if normalized == "accessory": + return "보물" + return _format_identifier_label(equipment_type) + + func _apply_item_button_icon(button: Button, item: Dictionary) -> void: var icon := _load_art_texture(str(item.get("icon", ""))) if icon == null: @@ -6647,12 +6673,12 @@ func _on_shop_item_pressed(item_id: String) -> void: var purchased := campaign_state.get_shop_purchase_count(active_scenario_id, item_id) if stock_limit >= 0 and purchased >= stock_limit: _play_ui_cancel() - _on_log_added("%s 품절." % item_name) + _on_log_added("%s 매진." % item_name) _rebuild_shop_menu() return if campaign_state.try_buy_item(item_id, price, active_scenario_id, stock_limit): state.set_inventory_snapshot(campaign_state.get_inventory_snapshot()) - _on_log_added("%s 매입: %dG." % [item_name, price]) + _on_log_added("%s 매입: %d냥." % [item_name, price]) else: _play_ui_cancel() _on_log_added("%s 매입 실패." % item_name) @@ -6670,7 +6696,7 @@ func _on_shop_sell_item_pressed(item_id: String) -> void: return if campaign_state.try_sell_item(item_id, sale_price): state.set_inventory_snapshot(campaign_state.get_inventory_snapshot()) - _on_log_added("%s 매각: %dG." % [item_name, sale_price]) + _on_log_added("%s 매각: %d냥." % [item_name, sale_price]) else: _play_ui_cancel() _on_log_added("%s 매각 실패." % item_name) @@ -6786,9 +6812,9 @@ func _format_post_battle_choice_text(choice: Dictionary) -> String: if description.is_empty(): text = label else: - text = "%s - %s" % [label, description] + text = "%s\n뜻: %s" % [label, description] if not reward_text.is_empty(): - text += "\n전리품: %s" % reward_text + text += "\n전리: %s" % reward_text return text @@ -6796,7 +6822,7 @@ func _format_post_battle_choice_reward_text(choice: Dictionary) -> String: var parts := [] var gold: int = maxi(0, int(choice.get("gold", 0))) if gold > 0: - parts.append("+%dG" % gold) + parts.append("+%d냥" % gold) if typeof(choice.get("items", [])) == TYPE_ARRAY: var items: Array = choice.get("items", []) if not items.is_empty(): @@ -6889,7 +6915,7 @@ func _format_battle_result_summary() -> String: if bool(battle_result_summary.get("rewards_applied", false)): var gold_reward := int(battle_result_summary.get("gold", 0)) if gold_reward > 0: - reward_lines.append("군자금 +%d" % gold_reward) + reward_lines.append("군자금 +%d냥" % gold_reward) if item_text != "없음": reward_lines.append("물자: %s" % item_text) else: @@ -6916,7 +6942,7 @@ func _format_battle_result_summary() -> String: var next_title := str(battle_result_summary.get("next_scenario_title", "")) if not next_title.is_empty(): next_text = "다음 행군: %s" % next_title - sections.append("전기\n 군자금: %dG\n %s\n %s" % [ + sections.append("전기\n 군자금: %d냥\n %s\n %s" % [ campaign_state.gold, saved_text, next_text @@ -7003,9 +7029,9 @@ func _format_progression_events(events) -> String: var event_type := str(event.get("type", "")) var unit_name := str(event.get("name", "부대")) if event_type == "promotion": - parts.append("%s -> %s" % [unit_name, str(event.get("to_class", "승급"))]) + parts.append("%s에서 %s로 승급" % [unit_name, str(event.get("to_class", "승급"))]) elif event_type == "level_up": - parts.append("%s Lv.%d" % [unit_name, int(event.get("to_level", 1))]) + parts.append("%s 품계 %d" % [unit_name, int(event.get("to_level", 1))]) if hidden_count > 0: parts.append("외 %d건" % hidden_count) if parts.is_empty(): @@ -7044,7 +7070,7 @@ func _format_inventory_items(inventory: Dictionary) -> String: var parts := [] for item_id in item_ids: var key := str(item_id) - parts.append("%s x%d" % [_item_inventory_display_name(key), int(inventory.get(key, 0))]) + parts.append("%s %d점" % [_item_inventory_display_name(key), int(inventory.get(key, 0))]) return _join_strings(parts, ", ") @@ -7075,7 +7101,7 @@ func _format_inventory_by_category(inventory: Dictionary) -> String: sections.append("잡물: %s" % _format_inventory_items(other)) if sections.is_empty(): return "없음" - return _join_strings(sections, " - ") + return _join_strings(sections, " · ") func _format_officer_id_list(values) -> String: @@ -7510,7 +7536,7 @@ func _format_post_move_tactic_button_text(skill_id: String, skill: Dictionary, s func _format_post_move_item_button_text(item_id: String, item: Dictionary, count: int) -> String: var marker := "> " if selected_item_id == item_id else "" var item_name := _item_display_name(item_id) - return "%s%s x%d %s" % [marker, item_name, count, _format_post_move_item_effect_text(item)] + return "%s%s 잔량 %d %s" % [marker, item_name, count, _format_post_move_item_effect_text(item)] func _format_post_move_item_effect_text(item: Dictionary) -> String: @@ -7957,7 +7983,7 @@ func _format_tactic_effect_text(skill: Dictionary) -> String: if not parts.is_empty(): var support_text := _join_strings(parts, ", ") return "%s, %s" % [support_text, area_text] if not area_text.is_empty() else support_text - var power_text := "P%d" % int(skill.get("power", 0)) + var power_text := "위력 %d" % int(skill.get("power", 0)) return "%s, %s" % [power_text, area_text] if not area_text.is_empty() else power_text @@ -8151,7 +8177,7 @@ func _clear_item_list() -> void: func _format_item_button_text(item_id: String, item: Dictionary, count: int) -> String: var marker := "> " if selected_item_id == item_id else "" var item_name := _item_display_name(item_id) - return "%s%s x%d %s" % [marker, item_name, count, _format_item_effect_text(item)] + return "%s%s 잔량 %d %s" % [marker, item_name, count, _format_item_effect_text(item)] func _format_item_effect_text(item: Dictionary) -> String: @@ -8336,7 +8362,7 @@ func _equipment_item_id(equipment: Dictionary, slot: String) -> String: func _format_equipment_option_text(unit: Dictionary, item_id: String, item: Dictionary, count: int) -> String: var parts := [ _item_display_name(item_id), - "x%d" % count, + "보유 %d점" % count, _format_equipment_bonus_text(item) ] var change_text := _format_equipment_change_text(unit, item) @@ -8442,7 +8468,7 @@ func _format_equipment_range_change_text(current_item: Dictionary, candidate_ite return "" if current_range.is_empty(): current_range = "-" - return "사거리 %s->%s" % [current_range, candidate_range] + return "사거리 %s에서 %s로" % [current_range, candidate_range] func _format_equipment_item_range_text(item: Dictionary) -> String: diff --git a/tools/smoke_event_ai_priority.gd b/tools/smoke_event_ai_priority.gd index 5df1cae..6159fcb 100644 --- a/tools/smoke_event_ai_priority.gd +++ b/tools/smoke_event_ai_priority.gd @@ -38,15 +38,15 @@ func _check_priority_action(state, failures: Array[String]) -> void: "type": "set_ai_target_priority", "unit_id": "xiahou_dun", "priority": 9, - "text": "Xiahou Dun draws the enemy's focus." + "text": "하후돈에게 적 시선이 몰립니다." }) var target: Dictionary = state.get_unit("xiahou_dun") if int(target.get("ai_target_priority", 0)) != 9: failures.append("AI target priority did not update on event action") - if not logs.has("Xiahou Dun draws the enemy's focus."): + if not logs.has("하후돈에게 적 시선이 몰립니다."): failures.append("AI priority event log missing") - if not _feedback_has(feedback, "xiahou_dun", "TARGET", "priority"): + if not _feedback_has(feedback, "xiahou_dun", "標的", "priority"): failures.append("AI priority feedback missing") diff --git a/tools/smoke_event_gold_pickups.gd b/tools/smoke_event_gold_pickups.gd index b958331..1e86421 100644 --- a/tools/smoke_event_gold_pickups.gd +++ b/tools/smoke_event_gold_pickups.gd @@ -64,7 +64,7 @@ func _check_wuchao_gold_pickup_persists_on_victory(failures: Array[String]) -> v failures.append("Wuchao depot should add 200 battle gold, got %d" % state.get_battle_gold_reward()) if not logs.has("Wuchao's captured pay chest yields 200 gold."): failures.append("Wuchao gold pickup log missing") - if not feedback.has("cao_cao_ch13|+200G|gold"): + if not feedback.has("cao_cao_ch13|+200냥|gold"): failures.append("Wuchao gold pickup feedback missing") var active_result: Dictionary = campaign_state.apply_battle_result(state) diff --git a/tools/smoke_event_item_pickups.gd b/tools/smoke_event_item_pickups.gd index 12a72ba..e72a104 100644 --- a/tools/smoke_event_item_pickups.gd +++ b/tools/smoke_event_item_pickups.gd @@ -43,12 +43,12 @@ func _check_wuchao_depot_pickup(failures: Array[String]) -> void: var after_inventory := state.get_inventory_snapshot() if int(after_inventory.get("bean", 0)) != int(before_inventory.get("bean", 0)) + 2: - failures.append("Wuchao depot should grant Bean x2: before %s after %s" % [str(before_inventory), str(after_inventory)]) + failures.append("Wuchao depot should grant 콩 2점: before %s after %s" % [str(before_inventory), str(after_inventory)]) if int(after_inventory.get("wine", 0)) != int(before_inventory.get("wine", 0)) + 1: - failures.append("Wuchao depot should grant Wine x1: before %s after %s" % [str(before_inventory), str(after_inventory)]) + failures.append("Wuchao depot should grant 술 1점: before %s after %s" % [str(before_inventory), str(after_inventory)]) if not logs.has("Usable Wuchao stores are seized before the granaries burn."): failures.append("Wuchao depot pickup log missing") - if not logs.has("전리품: 콩 x2."): + if not logs.has("전리품: 콩 2점."): failures.append("Bean pickup receipt log missing") if not logs.has("전리품: 술."): failures.append("Wine pickup receipt log missing") diff --git a/tools/smoke_item_debuff_cleanse.gd b/tools/smoke_item_debuff_cleanse.gd index 941526a..dfe5637 100644 --- a/tools/smoke_item_debuff_cleanse.gd +++ b/tools/smoke_item_debuff_cleanse.gd @@ -63,9 +63,9 @@ func _check_panacea_cleanses_debuffs(failures: Array[String]) -> void: for removed_text in ["무력 -3", "행군 -1", "독", "봉인"]: if summary.contains(removed_text): failures.append("Panacea should remove %s from summary: %s" % [removed_text, summary]) - _check_log_contains(failures, logs, "Cao Cao의 독 해소.") - _check_log_contains(failures, logs, "Cao Cao의 봉인 해소.") - _check_log_contains(failures, logs, "Cao Cao의 약화 해소: 무력 저하, 행군 저하.") + _check_log_contains(failures, logs, "조조의 독 해소.") + _check_log_contains(failures, logs, "조조의 봉인 해소.") + _check_log_contains(failures, logs, "조조의 약화 해소: 무력 저하, 행군 저하.") if not feedback.has("cao_cao|정화|support"): failures.append("Panacea cleanse feedback missing: %s" % str(feedback)) diff --git a/tools/smoke_objective_progress.gd b/tools/smoke_objective_progress.gd index b06d8d7..7aa2d04 100644 --- a/tools/smoke_objective_progress.gd +++ b/tools/smoke_objective_progress.gd @@ -17,7 +17,7 @@ func _init() -> void: failures, "001 commander defeat risk", _defeat_text("res://data/scenarios/001_yellow_turbans.json"), - "Cao Cao 건재" + "조조 건재" ) _check_contains( failures, diff --git a/tools/smoke_result_summary.gd b/tools/smoke_result_summary.gd index 3caf9e4..2f85a0f 100644 --- a/tools/smoke_result_summary.gd +++ b/tools/smoke_result_summary.gd @@ -27,7 +27,7 @@ func _init() -> void: "joined_officers": ["dian_wei"], "left_officers": [], "progression_events": [ - {"type": "level_up", "name": "Cao Cao", "to_level": 2} + {"type": "level_up", "name": "조조", "to_level": 2} ], "next_scenario_id": "002_sishui_gate", "next_scenario_title": "사수관 선봉전", @@ -36,10 +36,10 @@ func _init() -> void: } var result_text: String = scene._format_battle_result_summary() _check_contains(failures, "reward section", result_text, "전리품") - _check_contains(failures, "gold reward", result_text, "군자금 +100") - _check_contains(failures, "item reward", result_text, "콩 x2") + _check_contains(failures, "gold reward", result_text, "군자금 +100냥") + _check_contains(failures, "item reward", result_text, "콩 2점") _check_contains(failures, "roster section", result_text, "합류: 전위") - _check_contains(failures, "growth section", result_text, "Cao Cao Lv.2") + _check_contains(failures, "growth section", result_text, "조조 품계 2") _check_contains(failures, "campaign section", result_text, "다음 행군: 사수관 선봉전") _check_contains(failures, "next camp section", result_text, "다음 군막") _check_contains(failures, "next camp location", result_text, "사수관, 초평 원년") @@ -103,7 +103,7 @@ func _init() -> void: "items": ["war_axe"], "join_officers": ["dian_wei"] }) - _check_contains(failures, "choice gold", choice_text, "+50G") + _check_contains(failures, "choice gold", choice_text, "+50냥") _check_contains(failures, "choice item", choice_text, "전부") _check_contains(failures, "choice join", choice_text, "합류 전위") diff --git a/tools/smoke_visual_assets.gd b/tools/smoke_visual_assets.gd index 930efa4..60d6271 100644 --- a/tools/smoke_visual_assets.gd +++ b/tools/smoke_visual_assets.gd @@ -2572,26 +2572,26 @@ func _check_scene_texture_loading(failures: Array[String]) -> void: failures.append("camp overview should include %s: %s" % [expected, camp_overview]) var bean: Dictionary = scene.state.get_item_def("bean") var bean_buy_detail := scene._format_shop_buy_item_detail_text("bean", bean, int(bean.get("price", 0)), 0) - if not bean_buy_detail.contains("병력 +20") or not bean_buy_detail.contains("보유 x0"): + if not bean_buy_detail.contains("병력 +20") or not bean_buy_detail.contains("보유 0점"): failures.append("shop buy detail should summarize item effect and owned count") scene.campaign_state.gold = 10 var need_gold_detail := scene._format_shop_buy_item_detail_text("bean", bean, int(bean.get("price", 0)), 0) - if not need_gold_detail.contains("부족 40G"): + if not need_gold_detail.contains("부족 40냥"): failures.append("shop buy detail should explain missing gold") var sold_out_detail := scene._format_shop_buy_item_detail_text("bean", bean, int(bean.get("price", 0)), 2, 3, 0) - if not sold_out_detail.contains("재고 0/3") or not sold_out_detail.contains("품절"): + if not sold_out_detail.contains("잔량 0/3") or not sold_out_detail.contains("매진"): failures.append("shop buy detail should explain exhausted finite stock") var sell_detail := scene._format_shop_sell_item_detail_text("bean", bean, 25, 2) - if not sell_detail.contains("반값 매각") or not sell_detail.contains("보유 x2"): + if not sell_detail.contains("반값으로 넘김") or not sell_detail.contains("보유 2점"): failures.append("shop sell detail should summarize sale rule and owned count") var bean_action := scene._format_shop_buy_action_text("bean", bean, int(bean.get("price", 0))) - if not bean_action.contains("매입 콩") or not bean_action.contains("50G"): + if not bean_action.contains("매입 콩") or not bean_action.contains("50냥"): failures.append("shop buy action should be concise and priced") var bean_tooltip := scene._format_shop_item_tooltip_text( scene._format_shop_item_button_text("bean", bean, int(bean.get("price", 0)), 0), bean_buy_detail ) - if not bean_tooltip.contains("\n") or not bean_tooltip.contains("보유 x0"): + if not bean_tooltip.contains("\n") or not bean_tooltip.contains("보유 0점"): failures.append("shop item tooltip should preserve full item detail") scene.free() @@ -2643,7 +2643,7 @@ func _check_hud_focus_text(failures: Array[String]) -> void: var xiahou_dun: Dictionary = scene.state.get_unit("xiahou_dun") xiahou_dun["pos"] = Vector2i(3, 1) var forest_text := scene._unit_current_terrain_text(xiahou_dun) - if not forest_text.contains("수풀") or not forest_text.contains("행군 3"): + if not forest_text.contains("숲") or not forest_text.contains("행군 3"): failures.append("Cavalry movement should use mounted move_type cost on forest: %s" % forest_text) var archer: Dictionary = scene.state.get_unit("yellow_turban_3") var archer_text := scene._format_unit_focus_text(archer, "Hover") @@ -2653,7 +2653,7 @@ func _check_hud_focus_text(failures: Array[String]) -> void: failures.append("Archer HUD focus should clarify ranged attack affordance: %s" % archer_text) if not archer_text.contains("군령: 적군 군기"): failures.append("Enemy archer HUD focus should describe enemy control: %s" % archer_text) - if not scene._unit_current_terrain_text(archer).contains("평지"): + if not scene._unit_current_terrain_text(archer).contains("평원"): failures.append("Archer terrain text should reflect its current plain tile") _check_unit_class_mark(failures, scene, "cao_cao", "tactic", "策") _check_unit_class_mark(failures, scene, "xiahou_dun", "cavalry", "騎")