Antique briefing UI and Puyang localization
This commit is contained in:
@@ -76,7 +76,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "005_puyang_raid",
|
"id": "005_puyang_raid",
|
||||||
"title": "Puyang Raid",
|
"title": "복양 기습전",
|
||||||
"path": "res://data/scenarios/005_puyang_raid.json"
|
"path": "res://data/scenarios/005_puyang_raid.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"id": "005_puyang_raid",
|
"id": "005_puyang_raid",
|
||||||
"name": "Puyang Raid",
|
"name": "복양 기습전",
|
||||||
"objectives": {
|
"objectives": {
|
||||||
"victory": "Defeat Lu Bu's forward guard.",
|
"victory": "여포군 전위영을 격파하라.",
|
||||||
"defeat": "Cao Cao is defeated or the battle reaches Turn 11."
|
"defeat": "조조가 퇴각하거나 제11턴에 이르면 패한다."
|
||||||
},
|
},
|
||||||
"conditions": {
|
"conditions": {
|
||||||
"victory": { "type": "all_units_defeated", "team": "enemy", "after_event": "turn_3_lu_bu_arrives" },
|
"victory": { "type": "all_units_defeated", "team": "enemy", "after_event": "turn_3_lu_bu_arrives" },
|
||||||
@@ -13,77 +13,79 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"briefing": {
|
"briefing": {
|
||||||
"title": "Puyang Raid",
|
"title": "복양 기습전",
|
||||||
"location": "Puyang, 194 CE",
|
"location": "복양, 흥평 원년",
|
||||||
"lines": [
|
"lines": [
|
||||||
"Lu Bu has seized momentum in Yan Province.",
|
"연주가 흔들리자 여포는 복양을 움켜쥐고 기세를 돋우었다.",
|
||||||
"Cao Cao launches a night raid near Puyang to break the forward guard before the main cavalry can gather.",
|
"조조는 밤 그늘을 타고 전위영을 찔러, 적 기병이 말고삐를 모으기 전에 그 앞줄을 꺾으려 한다.",
|
||||||
"Dian Wei joins the front line as Cao Cao's personal shield."
|
"전위가 새로 군문에 들어와 주공의 깃발 곁을 지킨다."
|
||||||
],
|
],
|
||||||
"camp_conversations": [
|
"camp_conversations": [
|
||||||
{
|
{
|
||||||
"id": "puyang_night_raid_council",
|
"id": "puyang_night_raid_council",
|
||||||
"group": "officer",
|
"group": "officer",
|
||||||
"officer_id": "cao_cao",
|
"officer_id": "cao_cao",
|
||||||
"label": "Cao Cao - Night Raid",
|
"label": "조조 - 야습 군의",
|
||||||
"speaker": "Cao Cao",
|
"speaker": "Cao Cao",
|
||||||
"summary": "Review the timing of the strike against Lu Bu's forward guard.",
|
"display_speaker": "조조",
|
||||||
|
"summary": "여포군 전위영을 치는 시각과 퇴로를 정한다.",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Cao Cao", "side": "left", "text": "Lu Bu wins when a field becomes a race. Tonight we deny him daylight, distance, and the first clean charge." },
|
{ "speaker": "Cao Cao", "display_speaker": "조조", "side": "left", "text": "벌판이 달리기가 되면 여포가 이긴다. 오늘 밤에는 햇빛도, 거리도, 첫 돌격도 저들에게 주지 않겠다." },
|
||||||
{ "speaker": "Xiahou Dun", "side": "right", "text": "Then we hit the guard camp before the horses are bridled. I like battles that begin with the enemy half awake." }
|
{ "speaker": "Xiahou Dun", "display_speaker": "하후돈", "side": "right", "text": "그렇다면 말에 굴레가 얹히기 전에 영채를 치겠습니다. 적이 반쯤 잠든 전장은 우리 쪽 예법에 가깝습니다." }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "puyang_dian_wei_shield",
|
"id": "puyang_dian_wei_shield",
|
||||||
"group": "officer",
|
"group": "officer",
|
||||||
"officer_id": "dian_wei",
|
"officer_id": "dian_wei",
|
||||||
"label": "Dian Wei - Iron Shield",
|
"label": "전위 - 철문 호위",
|
||||||
"speaker": "Dian Wei",
|
"speaker": "Dian Wei",
|
||||||
"summary": "Hear Dian Wei's first pledge as Cao Cao's personal shield.",
|
"display_speaker": "전위",
|
||||||
|
"summary": "주공의 깃발 곁에 선 전위의 첫 맹세를 듣는다.",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Dian Wei", "side": "right", "text": "You gave me a place in the line. I will make that place difficult for any rider to cross." },
|
{ "speaker": "Dian Wei", "display_speaker": "전위", "side": "right", "text": "제게 대열 한가운데 자리를 주셨습니다. 그 자리는 어떤 기병도 쉽게 넘지 못하게 하겠습니다." },
|
||||||
{ "speaker": "Cao Cao", "side": "left", "text": "Stand close when the alarm rises. Lu Bu's men will aim for the banner before they understand the field." }
|
{ "speaker": "Cao Cao", "display_speaker": "조조", "side": "left", "text": "경고의 북이 울리면 내 깃발 가까이에 서라. 여포의 병사는 전장을 읽기 전에 먼저 군기를 노릴 것이다." }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "puyang_raider_stores",
|
"id": "puyang_raider_stores",
|
||||||
"group": "topic",
|
"group": "topic",
|
||||||
"label": "Raider Stores",
|
"label": "야습 보급 묶음",
|
||||||
"summary": "Pack a small supply bundle for the night raid.",
|
"summary": "밤길에 들고 갈 작은 군수 꾸러미를 챙긴다.",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Puyang Night Trader", "side": "right", "text": "A night raid does not leave room for wagons. I tied the beans into dark cloth so the men can carry them under armor." },
|
{ "speaker": "Puyang Night Trader", "display_speaker": "복양 야상", "side": "right", "text": "야습에는 큰 수레가 따라붙지 못합니다. 콩을 검은 천에 묶어 갑옷 밑에도 숨길 수 있게 했습니다." },
|
||||||
{ "speaker": "Xiahou Yuan", "side": "left", "text": "Good. When Lu Bu's riders wake, no one will have time to search a cart." }
|
{ "speaker": "Xiahou Yuan", "display_speaker": "하후연", "side": "left", "text": "좋다. 여포의 기병이 깨어나면 누구도 수레 속을 뒤질 틈이 없을 것이다." }
|
||||||
],
|
],
|
||||||
"effects": [
|
"effects": [
|
||||||
{ "type": "grant_item", "item_id": "bean", "count": 1, "text": "The raider stores add a Bean to the field supplies." }
|
{ "type": "grant_item", "item_id": "bean", "count": 1, "text": "야습 보급 묶음에서 콩 한 줌을 군수에 보탰다." }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "puyang_hardened_vanguard",
|
"id": "puyang_hardened_vanguard",
|
||||||
"campaign_flags": { "pursued_dong_zhuo": true },
|
"campaign_flags": { "pursued_dong_zhuo": true },
|
||||||
"group": "topic",
|
"group": "topic",
|
||||||
"label": "Hardened Vanguard",
|
"label": "형양 노병",
|
||||||
"summary": "Issue wine to veterans used to forced marches and sudden strikes.",
|
"summary": "강행군과 매복을 넘긴 선봉에게 술을 나눈다.",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Xiahou Dun", "side": "right", "text": "The men who chased Dong Zhuo still move before the drum finishes. Puyang's night road will not frighten them." },
|
{ "speaker": "Xiahou Dun", "display_speaker": "하후돈", "side": "right", "text": "동탁을 쫓아 형양까지 달린 병사들은 아직 북소리가 끝나기 전에 움직입니다. 복양의 밤길도 겁내지 않을 것입니다." },
|
||||||
{ "speaker": "Cao Cao", "side": "left", "text": "Give those veterans wine before we step off. Men who endure hard roads should know their endurance is seen." }
|
{ "speaker": "Cao Cao", "display_speaker": "조조", "side": "left", "text": "출진 전에 노병들에게 술을 조금 나누어라. 험한 길을 견딘 자에게는 그 수고를 안다는 말이 필요하다." }
|
||||||
],
|
],
|
||||||
"effects": [
|
"effects": [
|
||||||
{ "type": "grant_item", "item_id": "wine", "count": 1, "text": "The hardened vanguard adds Wine to the field supplies." }
|
{ "type": "grant_item", "item_id": "wine", "count": 1, "text": "형양 노병들이 술 한 병을 군수에 보탰다." }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "puyang_qingzhou_reserve_wagon",
|
"id": "puyang_qingzhou_reserve_wagon",
|
||||||
"campaign_flags": { "regrouped_after_sishui": true },
|
"campaign_flags": { "regrouped_after_sishui": true },
|
||||||
"group": "topic",
|
"group": "topic",
|
||||||
"label": "Qingzhou Reserve Wagon",
|
"label": "청주 예비 약거",
|
||||||
"summary": "Open a physician's bundle preserved during the steadier march.",
|
"summary": "정비 행군 중 보존한 의원의 꾸러미를 연다.",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Puyang Night Trader", "side": "right", "text": "The reserve wagon from Qingzhou still has a sealed physician's bundle. Quiet hands packed it better than hurried ones." },
|
{ "speaker": "Puyang Night Trader", "display_speaker": "복양 야상", "side": "right", "text": "청주에서 따라온 예비 수레에 아직 의원의 봉한 꾸러미가 남아 있습니다. 서두르지 않은 손이 싼 물건은 오래 버팁니다." },
|
||||||
{ "speaker": "Dian Wei", "side": "left", "text": "Keep it near the banner. If Lu Bu's riders break through, wounded men will need more than courage." }
|
{ "speaker": "Dian Wei", "display_speaker": "전위", "side": "left", "text": "깃발 가까이에 두게. 여포의 기병이 뚫고 들어오면 다친 병사에게 필요한 것은 담력만이 아닐 것이다." }
|
||||||
],
|
],
|
||||||
"effects": [
|
"effects": [
|
||||||
{ "type": "grant_item", "item_id": "panacea", "count": 1, "text": "The Qingzhou reserve wagon adds a Panacea to the field supplies." }
|
{ "type": "grant_item", "item_id": "panacea", "count": 1, "text": "청주 예비 약거에서 만능약 한 꾸러미를 군수에 보탰다." }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -100,10 +102,10 @@
|
|||||||
"iron_armor"
|
"iron_armor"
|
||||||
],
|
],
|
||||||
"merchant": {
|
"merchant": {
|
||||||
"name": "Puyang Night Trader",
|
"name": "복양 야상",
|
||||||
"lines": [
|
"lines": [
|
||||||
"Keep the lamps hooded. Lu Bu's scouts buy anything that shines.",
|
"등불은 가려 두십시오. 여포의 척후는 빛나는 물건이라면 무엇이든 사 갑니다.",
|
||||||
"His riders spend silver on speed. You will spend it on armor, beans, and living long enough to use both."
|
"저들의 기병은 빠른 말에 은을 쓰고, 장군께서는 갑옷과 콩, 그리고 그것을 쓸 만큼 오래 버티는 데 은을 쓰시면 됩니다."
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -167,7 +169,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unit_id": "zhang_liao_vanguard",
|
"unit_id": "zhang_liao_vanguard",
|
||||||
"name": "Zhang Liao Vanguard",
|
"name": "장료 선봉",
|
||||||
"class_id": "cavalry",
|
"class_id": "cavalry",
|
||||||
"team": "enemy",
|
"team": "enemy",
|
||||||
"level": 5,
|
"level": 5,
|
||||||
@@ -177,7 +179,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unit_id": "gao_shun_guard",
|
"unit_id": "gao_shun_guard",
|
||||||
"name": "Gao Shun Guard",
|
"name": "고순 군영",
|
||||||
"class_id": "infantry",
|
"class_id": "infantry",
|
||||||
"team": "enemy",
|
"team": "enemy",
|
||||||
"level": 5,
|
"level": 5,
|
||||||
@@ -187,7 +189,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unit_id": "puyang_cavalry_1",
|
"unit_id": "puyang_cavalry_1",
|
||||||
"name": "Puyang Rider",
|
"name": "복양 기병",
|
||||||
"class_id": "cavalry",
|
"class_id": "cavalry",
|
||||||
"team": "enemy",
|
"team": "enemy",
|
||||||
"level": 5,
|
"level": 5,
|
||||||
@@ -197,7 +199,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unit_id": "puyang_cavalry_2",
|
"unit_id": "puyang_cavalry_2",
|
||||||
"name": "Puyang Rider",
|
"name": "복양 기병",
|
||||||
"class_id": "cavalry",
|
"class_id": "cavalry",
|
||||||
"team": "enemy",
|
"team": "enemy",
|
||||||
"level": 5,
|
"level": 5,
|
||||||
@@ -207,7 +209,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unit_id": "puyang_archer",
|
"unit_id": "puyang_archer",
|
||||||
"name": "Puyang Archer",
|
"name": "복양 궁병",
|
||||||
"class_id": "archer",
|
"class_id": "archer",
|
||||||
"team": "enemy",
|
"team": "enemy",
|
||||||
"level": 5,
|
"level": 5,
|
||||||
@@ -222,7 +224,7 @@
|
|||||||
"once": true,
|
"once": true,
|
||||||
"when": { "type": "battle_start" },
|
"when": { "type": "battle_start" },
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "log", "text": "Cao Cao's raiding force slips toward Puyang under cover of darkness." }
|
{ "type": "log", "text": "조조의 야습대가 밤 그늘을 타고 복양 전위영으로 스며든다." }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -233,9 +235,9 @@
|
|||||||
{
|
{
|
||||||
"type": "dialogue",
|
"type": "dialogue",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Cao Cao", "text": "Lu Bu's cavalry is dangerous once it gathers speed. We strike before the whole camp wakes." },
|
{ "speaker": "Cao Cao", "display_speaker": "조조", "text": "여포의 기병은 속도가 붙으면 사납다. 영채가 모두 깨기 전에 쳐라." },
|
||||||
{ "speaker": "Dian Wei", "text": "Stay behind me, my lord. Any rider who reaches you answers to my axe." },
|
{ "speaker": "Dian Wei", "display_speaker": "전위", "text": "주공께서는 제 뒤에 계십시오. 주공께 닿는 말발굽은 제 도끼 앞에 설 것입니다." },
|
||||||
{ "speaker": "Xiahou Dun", "text": "Good. We cut open their guard and withdraw before dawn." }
|
{ "speaker": "Xiahou Dun", "display_speaker": "하후돈", "text": "좋습니다. 새벽이 오기 전에 전위영을 열고 빠져나가겠습니다." }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -245,12 +247,12 @@
|
|||||||
"once": true,
|
"once": true,
|
||||||
"when": { "type": "turn_start", "team": "enemy", "turn": 2 },
|
"when": { "type": "turn_start", "team": "enemy", "turn": 2 },
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "log", "text": "Puyang's forward camp sounds the alarm." },
|
{ "type": "log", "text": "복양 전위영에서 경고의 북이 울린다." },
|
||||||
{
|
{
|
||||||
"type": "dialogue",
|
"type": "dialogue",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Zhang Liao", "text": "Cao Cao comes in the night. Riders, close the road and pin him here." },
|
{ "speaker": "Zhang Liao", "display_speaker": "장료", "text": "조조가 밤을 틈타 왔다. 기병은 길을 닫고 저들을 이곳에 묶어라." },
|
||||||
{ "speaker": "Cao Cao", "text": "The alarm is raised. Break their line before Lu Bu himself arrives." }
|
{ "speaker": "Cao Cao", "display_speaker": "조조", "text": "북이 울렸구나. 여포가 직접 오기 전에 저 전열을 깨라." }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -260,25 +262,25 @@
|
|||||||
"once": true,
|
"once": true,
|
||||||
"when": { "type": "turn_start", "team": "enemy", "turn": 3 },
|
"when": { "type": "turn_start", "team": "enemy", "turn": 3 },
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "log", "text": "Lu Bu's banner appears beyond the eastern road." },
|
{ "type": "log", "text": "동쪽 길 너머로 여포의 군기가 모습을 드러낸다." },
|
||||||
{
|
{
|
||||||
"type": "dialogue",
|
"type": "dialogue",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Lu Bu", "text": "Cao Cao dares raid Puyang? Then let him see how fast my riders wake." },
|
{ "speaker": "Lu Bu", "display_speaker": "여포", "text": "조조가 감히 복양을 밤에 치느냐? 내 기병이 얼마나 빨리 깨어나는지 보여 주마." },
|
||||||
{ "speaker": "Dian Wei", "text": "That one has a loud voice. I will hold the road while you finish the guard." }
|
{ "speaker": "Dian Wei", "display_speaker": "전위", "text": "목소리 하나는 크군요. 주공께서 전위영을 깨는 동안 길목은 제가 막겠습니다." }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "set_objective",
|
"type": "set_objective",
|
||||||
"victory": "Defeat Zhang Liao's guard and the arriving riders.",
|
"victory": "장료의 전위와 달려든 기병을 격파하라.",
|
||||||
"defeat": "Cao Cao is defeated or the battle reaches Turn 11."
|
"defeat": "조조가 퇴각하거나 제11턴에 이르면 패한다."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "spawn_deployments",
|
"type": "spawn_deployments",
|
||||||
"deployments": [
|
"deployments": [
|
||||||
{
|
{
|
||||||
"unit_id": "lu_bu_banner",
|
"unit_id": "lu_bu_banner",
|
||||||
"name": "Lu Bu Banner Guard",
|
"name": "여포 기치병",
|
||||||
"class_id": "elite_cavalry",
|
"class_id": "elite_cavalry",
|
||||||
"team": "enemy",
|
"team": "enemy",
|
||||||
"level": 6,
|
"level": 6,
|
||||||
@@ -288,7 +290,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unit_id": "lu_bu_rider_north",
|
"unit_id": "lu_bu_rider_north",
|
||||||
"name": "Lu Bu Rider",
|
"name": "여포 기병",
|
||||||
"class_id": "cavalry",
|
"class_id": "cavalry",
|
||||||
"team": "enemy",
|
"team": "enemy",
|
||||||
"level": 5,
|
"level": 5,
|
||||||
@@ -298,7 +300,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unit_id": "lu_bu_rider_south",
|
"unit_id": "lu_bu_rider_south",
|
||||||
"name": "Lu Bu Rider",
|
"name": "여포 기병",
|
||||||
"class_id": "cavalry",
|
"class_id": "cavalry",
|
||||||
"team": "enemy",
|
"team": "enemy",
|
||||||
"level": 5,
|
"level": 5,
|
||||||
@@ -318,8 +320,8 @@
|
|||||||
{
|
{
|
||||||
"type": "dialogue",
|
"type": "dialogue",
|
||||||
"lines": [
|
"lines": [
|
||||||
{ "speaker": "Dian Wei", "text": "Their riders hit hard, but their line bends. Give the word and I will split it." },
|
{ "speaker": "Dian Wei", "display_speaker": "전위", "text": "저들의 기병은 세게 부딪치나 전열은 이미 휘었습니다. 명만 내리시면 제가 갈라 놓겠습니다." },
|
||||||
{ "speaker": "Cao Cao", "text": "Press them. We leave Puyang with their vanguard broken." }
|
{ "speaker": "Cao Cao", "display_speaker": "조조", "text": "몰아붙여라. 복양을 온전히 얻지 못하더라도, 오늘 밤 저들의 선봉은 꺾어 두고 간다." }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -330,21 +332,21 @@
|
|||||||
"items": ["bean", "wine", "iron_sword"]
|
"items": ["bean", "wine", "iron_sword"]
|
||||||
},
|
},
|
||||||
"post_battle_dialogue": [
|
"post_battle_dialogue": [
|
||||||
{ "speaker": "Xiahou Dun", "text": "Lu Bu's men still hold Puyang, but their forward guard will remember tonight." },
|
{ "speaker": "Xiahou Dun", "display_speaker": "하후돈", "text": "여포의 군세는 아직 복양을 붙들고 있으나, 전위영은 오늘 밤을 잊지 못할 것입니다." },
|
||||||
{ "speaker": "Dian Wei", "text": "They came fast. Next time, let them come closer." },
|
{ "speaker": "Dian Wei", "display_speaker": "전위", "text": "빠르게 달려오더군요. 다음에는 조금 더 가까이 오게 두십시오." },
|
||||||
{ "speaker": "Cao Cao", "text": "We have measured their strength. Now we choose whether to fortify Yan Province or strike again." }
|
{ "speaker": "Cao Cao", "display_speaker": "조조", "text": "저들의 힘을 가늠했다. 이제 연주를 굳힐지, 흔들린 복양을 다시 누를지 정해야 한다." }
|
||||||
],
|
],
|
||||||
"post_battle_choices": [
|
"post_battle_choices": [
|
||||||
{
|
{
|
||||||
"id": "fortify_yan_province",
|
"id": "fortify_yan_province",
|
||||||
"label": "Fortify Yan Province",
|
"label": "연주 보강",
|
||||||
"description": "Secure supply roads before another clash with Lu Bu.",
|
"description": "여포와 다시 겨루기 전에 군량길과 성책을 단단히 묶는다.",
|
||||||
"set_flags": { "fortified_yan_province": true, "pressed_lu_bu": false }
|
"set_flags": { "fortified_yan_province": true, "pressed_lu_bu": false }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "press_lu_bu",
|
"id": "press_lu_bu",
|
||||||
"label": "Press Lu Bu",
|
"label": "여포 압박",
|
||||||
"description": "Keep pressure on Puyang while Lu Bu's guard is shaken.",
|
"description": "전위영이 흔들린 틈을 놓치지 않고 복양을 계속 누른다.",
|
||||||
"set_flags": { "fortified_yan_province": false, "pressed_lu_bu": true }
|
"set_flags": { "fortified_yan_province": false, "pressed_lu_bu": true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,16 +7,21 @@ const CAMPAIGN_PATH := "res://data/campaign/campaign.json"
|
|||||||
const TILE_SIZE := 64
|
const TILE_SIZE := 64
|
||||||
const BOARD_OFFSET := Vector2(48, 104)
|
const BOARD_OFFSET := Vector2(48, 104)
|
||||||
const DEFAULT_BATTLE_BACKGROUND_PATH := "res://art/backgrounds/battlefield_frontier.png"
|
const DEFAULT_BATTLE_BACKGROUND_PATH := "res://art/backgrounds/battlefield_frontier.png"
|
||||||
const PLAYER_COLOR := Color(0.20, 0.42, 0.82)
|
const PLAYER_COLOR := Color(0.17, 0.38, 0.29)
|
||||||
const ENEMY_COLOR := Color(0.72, 0.18, 0.16)
|
const ENEMY_COLOR := Color(0.64, 0.085, 0.045)
|
||||||
const GRID_COLOR := Color(0.05, 0.06, 0.07, 0.45)
|
const GRID_COLOR := Color(0.12, 0.070, 0.032, 0.36)
|
||||||
const SKILL_OVERLAY_COLOR := Color(0.56, 0.28, 0.95, 0.28)
|
const MOVE_OVERLAY_COLOR := Color(0.72, 0.54, 0.24, 0.26)
|
||||||
const SKILL_AREA_OVERLAY_COLOR := Color(0.72, 0.46, 1.0, 0.30)
|
const MOVE_BORDER_COLOR := Color(0.94, 0.73, 0.36, 0.48)
|
||||||
const ITEM_OVERLAY_COLOR := Color(0.24, 0.74, 0.34, 0.30)
|
const ATTACK_OVERLAY_COLOR := Color(0.72, 0.055, 0.032, 0.24)
|
||||||
const FORMATION_OVERLAY_COLOR := Color(0.95, 0.76, 0.25, 0.34)
|
const ATTACK_BORDER_COLOR := Color(0.92, 0.34, 0.18, 0.50)
|
||||||
const OBJECTIVE_OVERLAY_COLOR := Color(1.0, 0.78, 0.18, 0.30)
|
const SKILL_OVERLAY_COLOR := Color(0.10, 0.25, 0.20, 0.28)
|
||||||
const THREAT_OVERLAY_COLOR := Color(1.0, 0.12, 0.10, 0.18)
|
const SKILL_AREA_OVERLAY_COLOR := Color(0.26, 0.34, 0.23, 0.30)
|
||||||
const THREAT_BORDER_COLOR := Color(1.0, 0.16, 0.12, 0.44)
|
const ITEM_OVERLAY_COLOR := Color(0.24, 0.42, 0.25, 0.28)
|
||||||
|
const ITEM_BORDER_COLOR := Color(0.58, 0.74, 0.42, 0.44)
|
||||||
|
const FORMATION_OVERLAY_COLOR := Color(0.78, 0.54, 0.18, 0.32)
|
||||||
|
const OBJECTIVE_OVERLAY_COLOR := Color(0.88, 0.52, 0.14, 0.30)
|
||||||
|
const THREAT_OVERLAY_COLOR := Color(0.76, 0.060, 0.035, 0.20)
|
||||||
|
const THREAT_BORDER_COLOR := Color(0.86, 0.18, 0.10, 0.48)
|
||||||
const BGM_MENU_PATH := "res://audio/bgm/menu_theme_placeholder.wav"
|
const BGM_MENU_PATH := "res://audio/bgm/menu_theme_placeholder.wav"
|
||||||
const BGM_BATTLE_PATH := "res://audio/bgm/battle_loop_placeholder.wav"
|
const BGM_BATTLE_PATH := "res://audio/bgm/battle_loop_placeholder.wav"
|
||||||
const SFX_BOW_RELEASE_PATH := "res://audio/sfx/bow_release_01.wav"
|
const SFX_BOW_RELEASE_PATH := "res://audio/sfx/bow_release_01.wav"
|
||||||
@@ -99,6 +104,35 @@ const UI_CHARCOAL_WASH := Color(0.045, 0.026, 0.016, 1.0)
|
|||||||
const UI_SCROLL_CENTER := Color(0.74, 0.58, 0.32, 0.996)
|
const UI_SCROLL_CENTER := Color(0.74, 0.58, 0.32, 0.996)
|
||||||
const UI_SCROLL_EDGE := Color(0.43, 0.25, 0.095, 0.996)
|
const UI_SCROLL_EDGE := Color(0.43, 0.25, 0.095, 0.996)
|
||||||
const MAP_SCROLL_FRAME_PADDING := 12.0
|
const MAP_SCROLL_FRAME_PADDING := 12.0
|
||||||
|
const SPEAKER_DISPLAY_NAMES := {
|
||||||
|
"Cao Cao": "조조",
|
||||||
|
"Xiahou Dun": "하후돈",
|
||||||
|
"Xiahou Yuan": "하후연",
|
||||||
|
"Cao Ren": "조인",
|
||||||
|
"Dian Wei": "전위",
|
||||||
|
"Guo Jia": "곽가",
|
||||||
|
"Zhang He": "장합",
|
||||||
|
"Zhang Liao": "장료",
|
||||||
|
"Gao Shun": "고순",
|
||||||
|
"Lu Bu": "여포",
|
||||||
|
"Puyang Night Trader": "복양 야상",
|
||||||
|
"Coalition Merchant": "군막 상인",
|
||||||
|
"Coalition Quartermaster": "연합 군수관",
|
||||||
|
"Camp Merchant": "군막 상인",
|
||||||
|
"Scout": "척후"
|
||||||
|
}
|
||||||
|
const SPEAKER_CANONICAL_NAMES := {
|
||||||
|
"조조": "Cao Cao",
|
||||||
|
"하후돈": "Xiahou Dun",
|
||||||
|
"하후연": "Xiahou Yuan",
|
||||||
|
"조인": "Cao Ren",
|
||||||
|
"전위": "Dian Wei",
|
||||||
|
"곽가": "Guo Jia",
|
||||||
|
"장합": "Zhang He",
|
||||||
|
"장료": "Zhang Liao",
|
||||||
|
"고순": "Gao Shun",
|
||||||
|
"여포": "Lu Bu"
|
||||||
|
}
|
||||||
|
|
||||||
var state: BattleState = BattleStateScript.new()
|
var state: BattleState = BattleStateScript.new()
|
||||||
var campaign_state: CampaignState = CampaignStateScript.new()
|
var campaign_state: CampaignState = CampaignStateScript.new()
|
||||||
@@ -949,7 +983,7 @@ func _create_hud() -> void:
|
|||||||
selected_row.add_child(selected_label)
|
selected_row.add_child(selected_label)
|
||||||
|
|
||||||
mission_title_label = Label.new()
|
mission_title_label = Label.new()
|
||||||
mission_title_label.text = "군령 목패"
|
mission_title_label.text = "軍令 목패"
|
||||||
mission_title_label.add_theme_font_size_override("font_size", 14)
|
mission_title_label.add_theme_font_size_override("font_size", 14)
|
||||||
_apply_label_style(mission_title_label, UI_OLD_BRONZE)
|
_apply_label_style(mission_title_label, UI_OLD_BRONZE)
|
||||||
side_column.add_child(mission_title_label)
|
side_column.add_child(mission_title_label)
|
||||||
@@ -1022,7 +1056,7 @@ func _create_hud() -> void:
|
|||||||
button_row.add_child(threat_button)
|
button_row.add_child(threat_button)
|
||||||
|
|
||||||
end_turn_button = Button.new()
|
end_turn_button = Button.new()
|
||||||
end_turn_button.text = "차례 종료"
|
end_turn_button.text = "군령 종료"
|
||||||
end_turn_button.pressed.connect(_on_end_turn_pressed)
|
end_turn_button.pressed.connect(_on_end_turn_pressed)
|
||||||
button_row.add_child(end_turn_button)
|
button_row.add_child(end_turn_button)
|
||||||
|
|
||||||
@@ -1255,7 +1289,7 @@ func _create_hud() -> void:
|
|||||||
briefing_column.add_child(briefing_location_label)
|
briefing_column.add_child(briefing_location_label)
|
||||||
|
|
||||||
briefing_column.add_child(_make_scroll_rod(680, 4))
|
briefing_column.add_child(_make_scroll_rod(680, 4))
|
||||||
briefing_column.add_child(_make_section_caption("軍令 승패 조서", 680))
|
briefing_column.add_child(_make_section_caption("軍令 勝敗 죽간", 680))
|
||||||
|
|
||||||
briefing_objective_panel = PanelContainer.new()
|
briefing_objective_panel = PanelContainer.new()
|
||||||
briefing_objective_panel.custom_minimum_size = Vector2(680, 104)
|
briefing_objective_panel.custom_minimum_size = Vector2(680, 104)
|
||||||
@@ -1279,7 +1313,7 @@ func _create_hud() -> void:
|
|||||||
briefing_objective_row.add_child(_make_bamboo_gutter(18, 84))
|
briefing_objective_row.add_child(_make_bamboo_gutter(18, 84))
|
||||||
|
|
||||||
briefing_column.add_child(_make_ink_wash_rule(680, 7))
|
briefing_column.add_child(_make_ink_wash_rule(680, 7))
|
||||||
briefing_column.add_child(_make_section_caption("비단 전장도 · 군막 장부", 680))
|
briefing_column.add_child(_make_section_caption("비단 전장도 · 군막 장계", 680))
|
||||||
|
|
||||||
briefing_camp_overview_panel = PanelContainer.new()
|
briefing_camp_overview_panel = PanelContainer.new()
|
||||||
briefing_camp_overview_panel.custom_minimum_size = Vector2(680, 102)
|
briefing_camp_overview_panel.custom_minimum_size = Vector2(680, 102)
|
||||||
@@ -1644,14 +1678,14 @@ func _create_hud() -> void:
|
|||||||
dialogue_control_row.add_child(dialogue_progress_label)
|
dialogue_control_row.add_child(dialogue_progress_label)
|
||||||
|
|
||||||
dialogue_previous_button = Button.new()
|
dialogue_previous_button = Button.new()
|
||||||
dialogue_previous_button.text = "이전 죽간"
|
dialogue_previous_button.text = "앞 죽간"
|
||||||
dialogue_previous_button.disabled = true
|
dialogue_previous_button.disabled = true
|
||||||
dialogue_previous_button.custom_minimum_size = Vector2(88, 32)
|
dialogue_previous_button.custom_minimum_size = Vector2(88, 32)
|
||||||
dialogue_previous_button.pressed.connect(_retreat_dialogue)
|
dialogue_previous_button.pressed.connect(_retreat_dialogue)
|
||||||
dialogue_control_row.add_child(dialogue_previous_button)
|
dialogue_control_row.add_child(dialogue_previous_button)
|
||||||
|
|
||||||
dialogue_continue_button = Button.new()
|
dialogue_continue_button = Button.new()
|
||||||
dialogue_continue_button.text = "다음 죽간"
|
dialogue_continue_button.text = "뒤 죽간"
|
||||||
dialogue_continue_button.custom_minimum_size = Vector2(120, 32)
|
dialogue_continue_button.custom_minimum_size = Vector2(120, 32)
|
||||||
dialogue_continue_button.pressed.connect(_advance_dialogue)
|
dialogue_continue_button.pressed.connect(_advance_dialogue)
|
||||||
dialogue_control_row.add_child(dialogue_continue_button)
|
dialogue_control_row.add_child(dialogue_continue_button)
|
||||||
@@ -2192,6 +2226,7 @@ func _draw_map() -> void:
|
|||||||
if background != null:
|
if background != null:
|
||||||
_draw_texture_cover(background, board_rect, Color(1.0, 1.0, 1.0, 0.96))
|
_draw_texture_cover(background, board_rect, Color(1.0, 1.0, 1.0, 0.96))
|
||||||
draw_rect(board_rect, Color(0.02, 0.025, 0.03, 0.12))
|
draw_rect(board_rect, Color(0.02, 0.025, 0.03, 0.12))
|
||||||
|
draw_rect(board_rect, Color(0.35, 0.22, 0.10, 0.10))
|
||||||
else:
|
else:
|
||||||
draw_rect(board_rect, Color(0.18, 0.26, 0.18))
|
draw_rect(board_rect, Color(0.18, 0.26, 0.18))
|
||||||
|
|
||||||
@@ -2305,9 +2340,9 @@ func _draw_texture_cover(texture: Texture2D, rect: Rect2, modulate: Color) -> vo
|
|||||||
|
|
||||||
func _terrain_fill_color(cell: Vector2i, terrain_key: String, has_background: bool) -> Color:
|
func _terrain_fill_color(cell: Vector2i, terrain_key: String, has_background: bool) -> Color:
|
||||||
var color := state.get_terrain_color(cell)
|
var color := state.get_terrain_color(cell)
|
||||||
var alpha := 0.16 if has_background else 0.34
|
var alpha := 0.13 if has_background else 0.34
|
||||||
if terrain_key == "W":
|
if terrain_key == "W":
|
||||||
alpha += 0.03
|
alpha += 0.04
|
||||||
elif terrain_key == "C" or terrain_key == "H":
|
elif terrain_key == "C" or terrain_key == "H":
|
||||||
alpha += 0.02
|
alpha += 0.02
|
||||||
color.a = alpha
|
color.a = alpha
|
||||||
@@ -2316,7 +2351,7 @@ func _terrain_fill_color(cell: Vector2i, terrain_key: String, has_background: bo
|
|||||||
|
|
||||||
func _map_grid_color(has_background: bool) -> Color:
|
func _map_grid_color(has_background: bool) -> Color:
|
||||||
var color := GRID_COLOR
|
var color := GRID_COLOR
|
||||||
color.a = 0.14 if has_background else 0.38
|
color.a = 0.09 if has_background else 0.34
|
||||||
return color
|
return color
|
||||||
|
|
||||||
|
|
||||||
@@ -2535,18 +2570,24 @@ func _draw_overlays() -> void:
|
|||||||
draw_rect(threat_rect.grow(-6.0), THREAT_BORDER_COLOR, false, 1.5)
|
draw_rect(threat_rect.grow(-6.0), THREAT_BORDER_COLOR, false, 1.5)
|
||||||
|
|
||||||
for cell in move_cells:
|
for cell in move_cells:
|
||||||
draw_rect(_rect_for_cell(cell), Color(0.16, 0.55, 0.95, 0.28))
|
var move_rect := _rect_for_cell(cell)
|
||||||
|
draw_rect(move_rect, MOVE_OVERLAY_COLOR)
|
||||||
|
draw_rect(move_rect.grow(-8.0), MOVE_BORDER_COLOR, false, 1.2)
|
||||||
|
|
||||||
if _has_pending_move() and state.is_inside(pending_move_to_cell):
|
if _has_pending_move() and state.is_inside(pending_move_to_cell):
|
||||||
var pending_rect := _rect_for_cell(pending_move_to_cell)
|
var pending_rect := _rect_for_cell(pending_move_to_cell)
|
||||||
draw_rect(pending_rect.grow(-4.0), Color(1.0, 0.82, 0.28, 0.32))
|
draw_rect(pending_rect.grow(-4.0), Color(UI_OLD_BRONZE.r, UI_OLD_BRONZE.g, UI_OLD_BRONZE.b, 0.34))
|
||||||
draw_rect(pending_rect.grow(-7.0), Color(1.0, 0.88, 0.36, 0.86), false, 2.0)
|
draw_rect(pending_rect.grow(-7.0), Color(UI_SEAL_RED.r, UI_SEAL_RED.g, UI_SEAL_RED.b, 0.72), false, 2.0)
|
||||||
|
|
||||||
for cell in attack_cells:
|
for cell in attack_cells:
|
||||||
draw_rect(_rect_for_cell(cell), Color(0.95, 0.22, 0.18, 0.24))
|
var attack_rect := _rect_for_cell(cell)
|
||||||
|
draw_rect(attack_rect, ATTACK_OVERLAY_COLOR)
|
||||||
|
draw_rect(attack_rect.grow(-7.0), ATTACK_BORDER_COLOR, false, 1.4)
|
||||||
|
|
||||||
for cell in skill_cells:
|
for cell in skill_cells:
|
||||||
draw_rect(_rect_for_cell(cell), SKILL_OVERLAY_COLOR)
|
var skill_rect := _rect_for_cell(cell)
|
||||||
|
draw_rect(skill_rect, SKILL_OVERLAY_COLOR)
|
||||||
|
draw_rect(skill_rect.grow(-8.0), Color(UI_MUTED_JADE.r, UI_MUTED_JADE.g, UI_MUTED_JADE.b, 0.54), false, 1.2)
|
||||||
|
|
||||||
if not selected_skill_id.is_empty() and skill_cells.has(hover_cell):
|
if not selected_skill_id.is_empty() and skill_cells.has(hover_cell):
|
||||||
var area_selected := state.get_selected_unit()
|
var area_selected := state.get_selected_unit()
|
||||||
@@ -2554,27 +2595,31 @@ func _draw_overlays() -> void:
|
|||||||
for cell in state.get_skill_area_cells(area_selected["id"], selected_skill_id, hover_cell):
|
for cell in state.get_skill_area_cells(area_selected["id"], selected_skill_id, hover_cell):
|
||||||
var area_rect := _rect_for_cell(cell)
|
var area_rect := _rect_for_cell(cell)
|
||||||
draw_rect(area_rect, SKILL_AREA_OVERLAY_COLOR)
|
draw_rect(area_rect, SKILL_AREA_OVERLAY_COLOR)
|
||||||
draw_rect(area_rect.grow(-7.0), Color(0.84, 0.62, 1.0, 0.62), false, 1.5)
|
draw_rect(area_rect.grow(-7.0), Color(UI_MUTED_JADE.r, UI_MUTED_JADE.g, UI_MUTED_JADE.b, 0.62), false, 1.5)
|
||||||
|
|
||||||
for cell in item_cells:
|
for cell in item_cells:
|
||||||
draw_rect(_rect_for_cell(cell), ITEM_OVERLAY_COLOR)
|
var item_rect := _rect_for_cell(cell)
|
||||||
|
draw_rect(item_rect, ITEM_OVERLAY_COLOR)
|
||||||
|
draw_rect(item_rect.grow(-8.0), ITEM_BORDER_COLOR, false, 1.2)
|
||||||
|
|
||||||
if formation_menu != null and formation_menu.visible:
|
if formation_menu != null and formation_menu.visible:
|
||||||
for cell in state.get_formation_cells():
|
for cell in state.get_formation_cells():
|
||||||
draw_rect(_rect_for_cell(cell), FORMATION_OVERLAY_COLOR)
|
var formation_rect := _rect_for_cell(cell)
|
||||||
|
draw_rect(formation_rect, FORMATION_OVERLAY_COLOR)
|
||||||
|
draw_rect(formation_rect.grow(-7.0), Color(UI_OLD_BRONZE.r, UI_OLD_BRONZE.g, UI_OLD_BRONZE.b, 0.58), false, 1.4)
|
||||||
|
|
||||||
if state.is_inside(hover_cell):
|
if state.is_inside(hover_cell):
|
||||||
var hover_color := Color(1.0, 1.0, 1.0, 0.22)
|
var hover_color := Color(UI_OLD_BRONZE.r, UI_OLD_BRONZE.g, UI_OLD_BRONZE.b, 0.42)
|
||||||
var hover_unit := state.get_unit_at(hover_cell)
|
var hover_unit := state.get_unit_at(hover_cell)
|
||||||
var selected := state.get_selected_unit()
|
var selected := state.get_selected_unit()
|
||||||
if formation_menu != null and formation_menu.visible and state.is_formation_cell(hover_cell):
|
if formation_menu != null and formation_menu.visible and state.is_formation_cell(hover_cell):
|
||||||
hover_color = Color(1.0, 0.86, 0.35, 0.62)
|
hover_color = Color(UI_OLD_BRONZE.r, UI_OLD_BRONZE.g, UI_OLD_BRONZE.b, 0.66)
|
||||||
elif not selected_skill_id.is_empty() and skill_cells.has(hover_cell):
|
elif not selected_skill_id.is_empty() and skill_cells.has(hover_cell):
|
||||||
hover_color = Color(0.72, 0.46, 1.0, 0.54)
|
hover_color = Color(UI_MUTED_JADE.r, UI_MUTED_JADE.g, UI_MUTED_JADE.b, 0.58)
|
||||||
elif not selected_item_id.is_empty() and item_cells.has(hover_cell):
|
elif not selected_item_id.is_empty() and item_cells.has(hover_cell):
|
||||||
hover_color = Color(0.36, 0.95, 0.42, 0.52)
|
hover_color = Color(0.52, 0.70, 0.30, 0.54)
|
||||||
elif not hover_unit.is_empty() and not selected.is_empty() and hover_unit.get("team", "") != selected.get("team", ""):
|
elif not hover_unit.is_empty() and not selected.is_empty() and hover_unit.get("team", "") != selected.get("team", ""):
|
||||||
hover_color = Color(1.0, 0.34, 0.24, 0.45)
|
hover_color = Color(UI_SEAL_RED.r, UI_SEAL_RED.g, UI_SEAL_RED.b, 0.52)
|
||||||
draw_rect(_rect_for_cell(hover_cell), hover_color, false, 3.0)
|
draw_rect(_rect_for_cell(hover_cell), hover_color, false, 3.0)
|
||||||
|
|
||||||
|
|
||||||
@@ -3591,12 +3636,12 @@ func _format_objective_hud_text() -> String:
|
|||||||
var lines := []
|
var lines := []
|
||||||
var victory := String(state.objectives.get("victory", "적군을 모두 격파하라."))
|
var victory := String(state.objectives.get("victory", "적군을 모두 격파하라."))
|
||||||
if not victory.is_empty():
|
if not victory.is_empty():
|
||||||
lines.append("승리 조서: %s" % victory)
|
lines.append("勝令: %s" % victory)
|
||||||
var defeat := String(state.objectives.get("defeat", ""))
|
var defeat := String(state.objectives.get("defeat", ""))
|
||||||
if not defeat.is_empty():
|
if not defeat.is_empty():
|
||||||
lines.append("패배 흉조: %s" % defeat)
|
lines.append("敗兆: %s" % defeat)
|
||||||
if lines.is_empty():
|
if lines.is_empty():
|
||||||
return "승리 조서"
|
return "勝令"
|
||||||
return _join_strings(lines, "\n")
|
return _join_strings(lines, "\n")
|
||||||
|
|
||||||
|
|
||||||
@@ -3792,24 +3837,24 @@ func _format_mission_panel_text() -> String:
|
|||||||
var lines := []
|
var lines := []
|
||||||
var victory := str(state.objectives.get("victory", ""))
|
var victory := str(state.objectives.get("victory", ""))
|
||||||
if not victory.is_empty():
|
if not victory.is_empty():
|
||||||
lines.append("승리 조서")
|
lines.append("勝令")
|
||||||
lines.append(" %s" % victory)
|
lines.append(" %s" % victory)
|
||||||
var defeat := str(state.objectives.get("defeat", ""))
|
var defeat := str(state.objectives.get("defeat", ""))
|
||||||
if not defeat.is_empty():
|
if not defeat.is_empty():
|
||||||
lines.append("패배 흉조")
|
lines.append("敗兆")
|
||||||
lines.append(" %s" % defeat)
|
lines.append(" %s" % defeat)
|
||||||
var progress_lines := state.get_objective_progress_lines(false, false)
|
var progress_lines := state.get_objective_progress_lines(false, false)
|
||||||
if not progress_lines.is_empty():
|
if not progress_lines.is_empty():
|
||||||
lines.append("전공 죽간")
|
lines.append("戰功 죽간")
|
||||||
for progress_line in progress_lines:
|
for progress_line in progress_lines:
|
||||||
lines.append(" %s" % progress_line)
|
lines.append(" %s" % progress_line)
|
||||||
var risk_lines := state.get_defeat_progress_lines()
|
var risk_lines := state.get_defeat_progress_lines()
|
||||||
if not risk_lines.is_empty():
|
if not risk_lines.is_empty():
|
||||||
lines.append("흉조 징후")
|
lines.append("凶兆 징후")
|
||||||
for risk_line in risk_lines:
|
for risk_line in risk_lines:
|
||||||
lines.append(" %s" % risk_line)
|
lines.append(" %s" % risk_line)
|
||||||
if lines.is_empty():
|
if lines.is_empty():
|
||||||
return "아직 봉인된 조서가 없습니다."
|
return "아직 봉인된 군령이 없습니다."
|
||||||
return _join_strings(lines, "\n")
|
return _join_strings(lines, "\n")
|
||||||
|
|
||||||
|
|
||||||
@@ -4254,18 +4299,18 @@ func _on_log_added(message: String) -> void:
|
|||||||
|
|
||||||
func _format_log_entry_text(message: String) -> String:
|
func _format_log_entry_text(message: String) -> String:
|
||||||
if message.begins_with("Objective updated:"):
|
if message.begins_with("Objective updated:"):
|
||||||
return "조서 개정:%s" % message.substr("Objective updated:".length())
|
return "軍令 개정:%s" % message.substr("Objective updated:".length())
|
||||||
if message.begins_with("Defeat condition updated:"):
|
if message.begins_with("Defeat condition updated:"):
|
||||||
return "흉조 개정:%s" % message.substr("Defeat condition updated:".length())
|
return "敗兆 개정:%s" % message.substr("Defeat condition updated:".length())
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
func _on_objective_updated(victory: String, defeat: String) -> void:
|
func _on_objective_updated(victory: String, defeat: String) -> void:
|
||||||
var notice_lines := ["새 조서 봉인"]
|
var notice_lines := ["새 軍令 봉인"]
|
||||||
if not victory.is_empty():
|
if not victory.is_empty():
|
||||||
notice_lines.append("승리 조서: %s" % victory)
|
notice_lines.append("勝令: %s" % victory)
|
||||||
if not defeat.is_empty():
|
if not defeat.is_empty():
|
||||||
notice_lines.append("패배 흉조: %s" % defeat)
|
notice_lines.append("敗兆: %s" % defeat)
|
||||||
if objective_notice_label != null:
|
if objective_notice_label != null:
|
||||||
objective_notice_label.text = "\n".join(notice_lines)
|
objective_notice_label.text = "\n".join(notice_lines)
|
||||||
if objective_notice_panel != null:
|
if objective_notice_panel != null:
|
||||||
@@ -4539,7 +4584,7 @@ func _normalized_dialogue_lines(lines: Array) -> Array:
|
|||||||
if text.is_empty():
|
if text.is_empty():
|
||||||
continue
|
continue
|
||||||
var speaker := str(line.get("speaker", ""))
|
var speaker := str(line.get("speaker", ""))
|
||||||
var display_speaker := str(line.get("display_speaker", speaker))
|
var display_speaker := _localized_speaker_name(str(line.get("display_speaker", speaker)))
|
||||||
result.append({
|
result.append({
|
||||||
"speaker": display_speaker,
|
"speaker": display_speaker,
|
||||||
"text": text,
|
"text": text,
|
||||||
@@ -4597,7 +4642,7 @@ func _render_dialogue_line() -> void:
|
|||||||
return
|
return
|
||||||
var line: Dictionary = active_dialogue_lines[active_dialogue_index]
|
var line: Dictionary = active_dialogue_lines[active_dialogue_index]
|
||||||
var speaker := str(line.get("speaker", ""))
|
var speaker := str(line.get("speaker", ""))
|
||||||
var display_speaker := str(line.get("display_speaker", speaker))
|
var display_speaker := _localized_speaker_name(str(line.get("display_speaker", speaker)))
|
||||||
var side := _normalized_dialogue_side(line.get("side", "left"))
|
var side := _normalized_dialogue_side(line.get("side", "left"))
|
||||||
_apply_dialogue_side(side)
|
_apply_dialogue_side(side)
|
||||||
dialogue_speaker_label.text = display_speaker
|
dialogue_speaker_label.text = display_speaker
|
||||||
@@ -4612,10 +4657,10 @@ func _render_dialogue_line() -> void:
|
|||||||
|
|
||||||
func _update_dialogue_controls() -> void:
|
func _update_dialogue_controls() -> void:
|
||||||
if dialogue_progress_label != null:
|
if dialogue_progress_label != null:
|
||||||
dialogue_progress_label.text = "죽간 %d / %d" % [active_dialogue_index + 1, active_dialogue_lines.size()]
|
dialogue_progress_label.text = "죽간 %d중 %d" % [active_dialogue_lines.size(), active_dialogue_index + 1]
|
||||||
if dialogue_previous_button != null:
|
if dialogue_previous_button != null:
|
||||||
dialogue_previous_button.disabled = active_dialogue_index <= 0
|
dialogue_previous_button.disabled = active_dialogue_index <= 0
|
||||||
dialogue_continue_button.text = "두루마리 봉인" if active_dialogue_index >= active_dialogue_lines.size() - 1 else "다음 죽간"
|
dialogue_continue_button.text = "두루마리 봉함" if active_dialogue_index >= active_dialogue_lines.size() - 1 else "뒤 죽간"
|
||||||
|
|
||||||
|
|
||||||
func _apply_dialogue_side(side: String) -> void:
|
func _apply_dialogue_side(side: String) -> void:
|
||||||
@@ -4640,6 +4685,20 @@ func _update_dialogue_portrait(speaker: String, portrait_path: String) -> void:
|
|||||||
dialogue_portrait_label.visible = not has_portrait and has_placeholder
|
dialogue_portrait_label.visible = not has_portrait and has_placeholder
|
||||||
|
|
||||||
|
|
||||||
|
func _localized_speaker_name(speaker: String) -> String:
|
||||||
|
var normalized_speaker := speaker.strip_edges()
|
||||||
|
if normalized_speaker.is_empty():
|
||||||
|
return ""
|
||||||
|
return str(SPEAKER_DISPLAY_NAMES.get(normalized_speaker, normalized_speaker))
|
||||||
|
|
||||||
|
|
||||||
|
func _canonical_speaker_name(speaker: String) -> String:
|
||||||
|
var normalized_speaker := speaker.strip_edges()
|
||||||
|
if normalized_speaker.is_empty():
|
||||||
|
return ""
|
||||||
|
return str(SPEAKER_CANONICAL_NAMES.get(normalized_speaker, normalized_speaker))
|
||||||
|
|
||||||
|
|
||||||
func _load_art_texture(texture_path: String) -> Texture2D:
|
func _load_art_texture(texture_path: String) -> Texture2D:
|
||||||
return _load_portrait_texture(texture_path)
|
return _load_portrait_texture(texture_path)
|
||||||
|
|
||||||
@@ -4990,27 +5049,27 @@ func _format_briefing_objectives() -> String:
|
|||||||
var text := ""
|
var text := ""
|
||||||
var victory := str(state.objectives.get("victory", ""))
|
var victory := str(state.objectives.get("victory", ""))
|
||||||
if not victory.is_empty():
|
if not victory.is_empty():
|
||||||
text = "승리 조서:\n %s" % victory
|
text = "勝令:\n %s" % victory
|
||||||
var defeat := str(state.objectives.get("defeat", ""))
|
var defeat := str(state.objectives.get("defeat", ""))
|
||||||
if not defeat.is_empty():
|
if not defeat.is_empty():
|
||||||
if not text.is_empty():
|
if not text.is_empty():
|
||||||
text += "\n"
|
text += "\n"
|
||||||
text += "패배 흉조:\n %s" % defeat
|
text += "敗兆:\n %s" % defeat
|
||||||
var progress_lines := state.get_objective_progress_lines(false, false)
|
var progress_lines := state.get_objective_progress_lines(false, false)
|
||||||
if not progress_lines.is_empty():
|
if not progress_lines.is_empty():
|
||||||
if not text.is_empty():
|
if not text.is_empty():
|
||||||
text += "\n"
|
text += "\n"
|
||||||
text += "전공 죽간:\n %s" % _join_strings(progress_lines, ", ")
|
text += "戰功 죽간:\n %s" % _join_strings(progress_lines, ", ")
|
||||||
var risk_lines := state.get_defeat_progress_lines()
|
var risk_lines := state.get_defeat_progress_lines()
|
||||||
if not risk_lines.is_empty():
|
if not risk_lines.is_empty():
|
||||||
if not text.is_empty():
|
if not text.is_empty():
|
||||||
text += "\n"
|
text += "\n"
|
||||||
text += "흉조 징후:\n %s" % _join_strings(risk_lines, ", ")
|
text += "凶兆 징후:\n %s" % _join_strings(risk_lines, ", ")
|
||||||
var rewards_text := _format_briefing_rewards()
|
var rewards_text := _format_briefing_rewards()
|
||||||
if not rewards_text.is_empty():
|
if not rewards_text.is_empty():
|
||||||
if not text.is_empty():
|
if not text.is_empty():
|
||||||
text += "\n"
|
text += "\n"
|
||||||
text += "전리품 봉인:\n %s" % rewards_text
|
text += "戰利 봉인:\n %s" % rewards_text
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
@@ -5512,7 +5571,7 @@ func _camp_conversation_entries() -> Array:
|
|||||||
|
|
||||||
func _format_camp_conversation_button_text(conversation: Dictionary) -> String:
|
func _format_camp_conversation_button_text(conversation: Dictionary) -> String:
|
||||||
var label := str(conversation.get("label", "군막 담화"))
|
var label := str(conversation.get("label", "군막 담화"))
|
||||||
var speaker := str(conversation.get("speaker", ""))
|
var speaker := _localized_speaker_name(str(conversation.get("speaker", "")))
|
||||||
var summary := str(conversation.get("summary", ""))
|
var summary := str(conversation.get("summary", ""))
|
||||||
var group := _camp_conversation_group_text(str(conversation.get("group", "topic")))
|
var group := _camp_conversation_group_text(str(conversation.get("group", "topic")))
|
||||||
var parts := [group, label]
|
var parts := [group, label]
|
||||||
@@ -5563,13 +5622,13 @@ func _camp_conversation_group_text(group: String) -> String:
|
|||||||
func _camp_conversation_preview_speaker(conversation: Dictionary) -> String:
|
func _camp_conversation_preview_speaker(conversation: Dictionary) -> String:
|
||||||
var speaker := str(conversation.get("speaker", "")).strip_edges()
|
var speaker := str(conversation.get("speaker", "")).strip_edges()
|
||||||
if not speaker.is_empty():
|
if not speaker.is_empty():
|
||||||
return speaker
|
return _localized_speaker_name(speaker)
|
||||||
for line in conversation.get("lines", []):
|
for line in conversation.get("lines", []):
|
||||||
if typeof(line) != TYPE_DICTIONARY:
|
if typeof(line) != TYPE_DICTIONARY:
|
||||||
continue
|
continue
|
||||||
speaker = str(line.get("speaker", "")).strip_edges()
|
speaker = str(line.get("speaker", "")).strip_edges()
|
||||||
if not speaker.is_empty():
|
if not speaker.is_empty():
|
||||||
return speaker
|
return _localized_speaker_name(speaker)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@@ -5600,7 +5659,7 @@ func _camp_conversation_preview_portrait_path(conversation: Dictionary) -> Strin
|
|||||||
return portrait
|
return portrait
|
||||||
var speaker := _camp_conversation_preview_speaker(conversation)
|
var speaker := _camp_conversation_preview_speaker(conversation)
|
||||||
if not speaker.is_empty():
|
if not speaker.is_empty():
|
||||||
return state.data_catalog.get_portrait_for_speaker(speaker)
|
return state.data_catalog.get_portrait_for_speaker(_canonical_speaker_name(speaker))
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@@ -7372,7 +7431,7 @@ func _rebuild_post_move_item_picker(selected: Dictionary) -> void:
|
|||||||
_apply_item_button_icon(item_button, item)
|
_apply_item_button_icon(item_button, item)
|
||||||
var disabled_reason := _post_move_item_disabled_reason(selected, item_id, count)
|
var disabled_reason := _post_move_item_disabled_reason(selected, item_id, count)
|
||||||
item_button.disabled = not disabled_reason.is_empty()
|
item_button.disabled = not disabled_reason.is_empty()
|
||||||
item_button.tooltip_text = disabled_reason if not disabled_reason.is_empty() else "Select this supply."
|
item_button.tooltip_text = disabled_reason if not disabled_reason.is_empty() else "이 보급을 군령에 올립니다."
|
||||||
_apply_button_style(item_button)
|
_apply_button_style(item_button)
|
||||||
item_button.pressed.connect(_on_post_move_item_option_pressed.bind(item_id))
|
item_button.pressed.connect(_on_post_move_item_option_pressed.bind(item_id))
|
||||||
post_move_picker_list.add_child(item_button)
|
post_move_picker_list.add_child(item_button)
|
||||||
@@ -7697,9 +7756,9 @@ func _update_end_turn_button() -> void:
|
|||||||
return
|
return
|
||||||
var phase_block := _action_phase_block_reason()
|
var phase_block := _action_phase_block_reason()
|
||||||
if not phase_block.is_empty():
|
if not phase_block.is_empty():
|
||||||
_set_action_button_blocked(end_turn_button, "차례 종료", str(phase_block.get("label", "처리 중")), str(phase_block.get("tooltip", "")))
|
_set_action_button_blocked(end_turn_button, "군령 종료", str(phase_block.get("label", "처리 중")), str(phase_block.get("tooltip", "")))
|
||||||
return
|
return
|
||||||
_set_action_button_state(end_turn_button, "차례 종료", false, "아군 차례를 마치고 적군이 움직입니다.")
|
_set_action_button_state(end_turn_button, "군령 종료", false, "아군 군령을 거두고 적군의 차례로 넘깁니다.")
|
||||||
|
|
||||||
|
|
||||||
func _update_threat_button() -> void:
|
func _update_threat_button() -> void:
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ func _check_puyang_raid_camp_supplies(failures: Array[String]) -> void:
|
|||||||
scene.free()
|
scene.free()
|
||||||
return
|
return
|
||||||
var merchant: Dictionary = scene.state.get_shop_merchant()
|
var merchant: Dictionary = scene.state.get_shop_merchant()
|
||||||
if str(merchant.get("name", "")) != "Puyang Night Trader":
|
if str(merchant.get("name", "")) != "복양 야상":
|
||||||
failures.append("Puyang shop merchant name should be present")
|
failures.append("Puyang shop merchant name should be present")
|
||||||
var merchant_lines: Array = merchant.get("lines", [])
|
var merchant_lines: Array = merchant.get("lines", [])
|
||||||
if merchant_lines.size() < 2:
|
if merchant_lines.size() < 2:
|
||||||
|
|||||||
@@ -211,16 +211,16 @@ func _check_objective_notice(failures: Array[String]) -> void:
|
|||||||
scene._on_objective_updated("Defeat the new vanguard.", "")
|
scene._on_objective_updated("Defeat the new vanguard.", "")
|
||||||
if scene.objective_notice_panel == null or not scene.objective_notice_panel.visible:
|
if scene.objective_notice_panel == null or not scene.objective_notice_panel.visible:
|
||||||
failures.append("objective notice panel should be visible after objective update")
|
failures.append("objective notice panel should be visible after objective update")
|
||||||
elif not scene.objective_notice_label.text.contains("새 조서 봉인") or not scene.objective_notice_label.text.contains("승리 조서: Defeat the new vanguard."):
|
elif not scene.objective_notice_label.text.contains("새 軍令 봉인") or not scene.objective_notice_label.text.contains("勝令: Defeat the new vanguard."):
|
||||||
failures.append("objective notice label should use sealed edict wording: %s" % scene.objective_notice_label.text)
|
failures.append("objective notice label should use sealed edict wording: %s" % scene.objective_notice_label.text)
|
||||||
scene._on_objective_updated("", "Supply train is lost.")
|
scene._on_objective_updated("", "Supply train is lost.")
|
||||||
if scene.objective_notice_panel == null or not scene.objective_notice_panel.visible:
|
if scene.objective_notice_panel == null or not scene.objective_notice_panel.visible:
|
||||||
failures.append("objective notice panel should be visible after defeat update")
|
failures.append("objective notice panel should be visible after defeat update")
|
||||||
elif not scene.objective_notice_label.text.contains("새 조서 봉인") or not scene.objective_notice_label.text.contains("패배 흉조: Supply train is lost."):
|
elif not scene.objective_notice_label.text.contains("새 軍令 봉인") or not scene.objective_notice_label.text.contains("敗兆: Supply train is lost."):
|
||||||
failures.append("objective notice label should use omen wording: %s" % scene.objective_notice_label.text)
|
failures.append("objective notice label should use omen wording: %s" % scene.objective_notice_label.text)
|
||||||
if scene._format_log_entry_text("Objective updated: Defeat the new vanguard.") != "조서 개정: Defeat the new vanguard.":
|
if scene._format_log_entry_text("Objective updated: Defeat the new vanguard.") != "軍令 개정: Defeat the new vanguard.":
|
||||||
failures.append("objective log display should use edict wording")
|
failures.append("objective log display should use edict wording")
|
||||||
if scene._format_log_entry_text("Defeat condition updated: Supply train is lost.") != "흉조 개정: Supply train is lost.":
|
if scene._format_log_entry_text("Defeat condition updated: Supply train is lost.") != "敗兆 개정: Supply train is lost.":
|
||||||
failures.append("defeat log display should use omen wording")
|
failures.append("defeat log display should use omen wording")
|
||||||
if scene.objective_notice_timer <= 0.0:
|
if scene.objective_notice_timer <= 0.0:
|
||||||
failures.append("objective notice timer should be active")
|
failures.append("objective notice timer should be active")
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
|
|||||||
_check_camp_conversation(failures, puyang_conversations[2], "puyang_raider_stores", "topic", "")
|
_check_camp_conversation(failures, puyang_conversations[2], "puyang_raider_stores", "topic", "")
|
||||||
_check_camp_conversation_effect(failures, puyang_conversations[2], "bean", 1)
|
_check_camp_conversation_effect(failures, puyang_conversations[2], "bean", 1)
|
||||||
var puyang_merchant := puyang_state.get_shop_merchant()
|
var puyang_merchant := puyang_state.get_shop_merchant()
|
||||||
if str(puyang_merchant.get("name", "")) != "Puyang Night Trader":
|
if str(puyang_merchant.get("name", "")) != "복양 야상":
|
||||||
failures.append("005 shop should expose Puyang merchant name")
|
failures.append("005 shop should expose Puyang merchant name")
|
||||||
if (puyang_merchant.get("lines", []) as Array).size() < 2:
|
if (puyang_merchant.get("lines", []) as Array).size() < 2:
|
||||||
failures.append("005 shop should expose merchant flavor lines")
|
failures.append("005 shop should expose merchant flavor lines")
|
||||||
@@ -2672,14 +2672,14 @@ func _check_ancient_ui_theme(failures: Array[String]) -> void:
|
|||||||
scene.free()
|
scene.free()
|
||||||
return
|
return
|
||||||
var briefing_text := scene._format_briefing_objectives()
|
var briefing_text := scene._format_briefing_objectives()
|
||||||
for expected in ["승리 조서:", "패배 흉조:", "전공 죽간:", "흉조 징후:", "전리품 봉인:"]:
|
for expected in ["勝令:", "敗兆:", "戰功 죽간:", "凶兆 징후:", "戰利 봉인:"]:
|
||||||
if not briefing_text.contains(expected):
|
if not briefing_text.contains(expected):
|
||||||
failures.append("briefing objective parchment should use ancient heading `%s`: %s" % [expected, briefing_text])
|
failures.append("briefing objective parchment should use ancient heading `%s`: %s" % [expected, briefing_text])
|
||||||
var hud_objective := scene._format_objective_hud_text()
|
var hud_objective := scene._format_objective_hud_text()
|
||||||
if not hud_objective.contains("승리 조서:") or not hud_objective.contains("패배 흉조:"):
|
if not hud_objective.contains("勝令:") or not hud_objective.contains("敗兆:"):
|
||||||
failures.append("HUD objective should read as paired edict and omen text: %s" % hud_objective)
|
failures.append("HUD objective should read as paired edict and omen text: %s" % hud_objective)
|
||||||
var mission_text := scene._format_mission_panel_text()
|
var mission_text := scene._format_mission_panel_text()
|
||||||
for expected in ["승리 조서", "패배 흉조", "전공 죽간", "흉조 징후"]:
|
for expected in ["勝令", "敗兆", "戰功 죽간", "凶兆 징후"]:
|
||||||
if not mission_text.contains(expected):
|
if not mission_text.contains(expected):
|
||||||
failures.append("mission panel should use old campaign wording `%s`: %s" % [expected, mission_text])
|
failures.append("mission panel should use old campaign wording `%s`: %s" % [expected, mission_text])
|
||||||
_check_panel_style_fill(failures, scene.briefing_panel, "briefing panel", Color(0.68, 0.50, 0.25, 0.997))
|
_check_panel_style_fill(failures, scene.briefing_panel, "briefing panel", Color(0.68, 0.50, 0.25, 0.997))
|
||||||
@@ -2702,9 +2702,9 @@ func _check_ancient_ui_theme(failures: Array[String]) -> void:
|
|||||||
_check_hanging_tassel(failures, scene.dialogue_left_tassel, "dialogue left tassel")
|
_check_hanging_tassel(failures, scene.dialogue_left_tassel, "dialogue left tassel")
|
||||||
_check_hanging_tassel(failures, scene.dialogue_right_tassel, "dialogue right tassel")
|
_check_hanging_tassel(failures, scene.dialogue_right_tassel, "dialogue right tassel")
|
||||||
_check_dialogue_column_budget(failures, scene)
|
_check_dialogue_column_budget(failures, scene)
|
||||||
if scene.dialogue_continue_button == null or scene.dialogue_continue_button.text != "다음 죽간":
|
if scene.dialogue_continue_button == null or scene.dialogue_continue_button.text != "뒤 죽간":
|
||||||
failures.append("dialogue continue button should use ancient slip text")
|
failures.append("dialogue continue button should use ancient slip text")
|
||||||
if scene.dialogue_previous_button == null or scene.dialogue_previous_button.text != "이전 죽간":
|
if scene.dialogue_previous_button == null or scene.dialogue_previous_button.text != "앞 죽간":
|
||||||
failures.append("dialogue previous button should use ancient slip text")
|
failures.append("dialogue previous button should use ancient slip text")
|
||||||
var localized_lines := scene._normalized_dialogue_lines([{"speaker": "Cao Cao", "display_speaker": "조조", "text": "군령을 전하라."}])
|
var localized_lines := scene._normalized_dialogue_lines([{"speaker": "Cao Cao", "display_speaker": "조조", "text": "군령을 전하라."}])
|
||||||
if localized_lines.is_empty() or str((localized_lines[0] as Dictionary).get("speaker", "")) != "조조":
|
if localized_lines.is_empty() or str((localized_lines[0] as Dictionary).get("speaker", "")) != "조조":
|
||||||
@@ -2739,7 +2739,7 @@ func _check_ancient_ui_theme(failures: Array[String]) -> void:
|
|||||||
failures.append("dialogue text should use the project serif font override")
|
failures.append("dialogue text should use the project serif font override")
|
||||||
if scene.dialogue_continue_button == null or not scene.dialogue_continue_button.has_theme_font_override("font"):
|
if scene.dialogue_continue_button == null or not scene.dialogue_continue_button.has_theme_font_override("font"):
|
||||||
failures.append("dialogue continue button should use the project serif font override")
|
failures.append("dialogue continue button should use the project serif font override")
|
||||||
if scene.mission_title_label == null or scene.mission_title_label.text != "군령 목패":
|
if scene.mission_title_label == null or scene.mission_title_label.text != "軍令 목패":
|
||||||
failures.append("mission panel title should use bronze tablet wording")
|
failures.append("mission panel title should use bronze tablet wording")
|
||||||
if scene.shop_button == null or scene.shop_button.text != "군상":
|
if scene.shop_button == null or scene.shop_button.text != "군상":
|
||||||
failures.append("briefing shop button should use sutler wording")
|
failures.append("briefing shop button should use sutler wording")
|
||||||
@@ -2968,7 +2968,7 @@ func _check_action_button_disabled_reasons(failures: Array[String]) -> void:
|
|||||||
|
|
||||||
scene.state.current_team = BattleState.TEAM_ENEMY
|
scene.state.current_team = BattleState.TEAM_ENEMY
|
||||||
scene._update_end_turn_button()
|
scene._update_end_turn_button()
|
||||||
if scene.end_turn_button.text != "차례 종료 - 적군 차례" or not scene.end_turn_button.tooltip_text.contains("아군 군령"):
|
if scene.end_turn_button.text != "군령 종료 - 적군 차례" or not scene.end_turn_button.tooltip_text.contains("아군 군령"):
|
||||||
failures.append("enemy phase should explain disabled end turn button: %s | %s" % [scene.end_turn_button.text, scene.end_turn_button.tooltip_text])
|
failures.append("enemy phase should explain disabled end turn button: %s | %s" % [scene.end_turn_button.text, scene.end_turn_button.tooltip_text])
|
||||||
|
|
||||||
scene.state.current_team = BattleState.TEAM_PLAYER
|
scene.state.current_team = BattleState.TEAM_PLAYER
|
||||||
|
|||||||
Reference in New Issue
Block a user