Add Jing rear crisis chapter
This commit is contained in:
@@ -65,16 +65,17 @@ Build a small complete tactical RPG loop that can grow into a longer Romance of
|
|||||||
- Thirty-ninth battle Fan Castle outer-front route, locking Liu Bei and Guan Yu as required sortie officers while the player chooses five support officers from the twenty-two-officer roster to pressure Pang De, Cao Ren, and Yu Jin
|
- Thirty-ninth battle Fan Castle outer-front route, locking Liu Bei and Guan Yu as required sortie officers while the player chooses five support officers from the twenty-two-officer roster to pressure Pang De, Cao Ren, and Yu Jin
|
||||||
- Fortieth battle Han River flood route, using Guan Yu's water-control plan across an 80x62 flooded battlefield to break Yu Jin's seven armies and open the Fan Castle siege setup
|
- Fortieth battle Han River flood route, using Guan Yu's water-control plan across an 80x62 flooded battlefield to break Yu Jin's seven armies and open the Fan Castle siege setup
|
||||||
- Forty-first battle Fan Castle siege route, using a twenty-two-officer roster across an 82x64 castle battlefield to pressure Cao Ren's gate line, Pang De's desperate cavalry, and Wu's rear-shadow scouts
|
- Forty-first battle Fan Castle siege route, using a twenty-two-officer roster across an 82x64 castle battlefield to pressure Cao Ren's gate line, Pang De's desperate cavalry, and Wu's rear-shadow scouts
|
||||||
|
- Forty-second battle Jing rear-crisis route, using Ma Liang and Mi Zhu's rear-guard roles across an 84x66 Jiangling ferry battlefield to repel Lu Meng's disguised scouts and expose Mi Fang's wavering rear line
|
||||||
- Camp progress timeline tab that summarizes Liu Bei's long campaign arc, completed battles, current chapter, latest battle, and next major chapter
|
- Camp progress timeline tab that summarizes Liu Bei's long campaign arc, completed battles, current chapter, latest battle, and next major chapter
|
||||||
- Tactical sortie preparation panel with battle-specific sortie limits, recommended officers with reasons, class role, named equipment, core stats, bond partner, next-map terrain suitability, deployment preview, formation roles, active bond count, recruited-officer count, reserve roster summary, and readiness advice for each deployable officer
|
- Tactical sortie preparation panel with battle-specific sortie limits, recommended officers with reasons, class role, named equipment, core stats, bond partner, next-map terrain suitability, deployment preview, formation roles, active bond count, recruited-officer count, reserve roster summary, and readiness advice for each deployable officer
|
||||||
- Officer collection support in camp, including full roster status, selected/reserve/recommended markers, and post-battle reserve training growth for benched officers
|
- Officer collection support in camp, including full roster status, selected/reserve/recommended markers, and post-battle reserve training growth for benched officers
|
||||||
- Treasure equipment effects wired into battle previews and resolution, including named weapon damage bonuses, defensive treasure mitigation, support recovery bonuses, turn-start charm recovery, and equipment-specific growth bonuses
|
- Treasure equipment effects wired into battle previews and resolution, including named weapon damage bonuses, defensive treasure mitigation, support recovery bonuses, turn-start charm recovery, and equipment-specific growth bonuses
|
||||||
- Flow verification script from title through the forty-first battle victory, King of Hanzhong council milestone, Shu-Han foundation milestone, recruit sortie selection, Liu Biao visit rewards, Zhuge Liang recruitment, Bowang/Changban/Jiangdong/Red Cliffs/Jing Province/Guiyang/Wuling/Changsha/Yi Province/Fu Pass/Luo Castle/Luofeng/Luo main gate/Mianzhu/Chengdu/Jiameng/Yangping/Dingjun/Hanzhong/Jing defense/Fan Castle/Han River/Fan siege camp states, campaign timeline state, and camp save state
|
- Flow verification script from title through the forty-second battle victory, King of Hanzhong council milestone, Shu-Han foundation milestone, recruit sortie selection, Liu Biao visit rewards, Zhuge Liang recruitment, Bowang/Changban/Jiangdong/Red Cliffs/Jing Province/Guiyang/Wuling/Changsha/Yi Province/Fu Pass/Luo Castle/Luofeng/Luo main gate/Mianzhu/Chengdu/Jiameng/Yangping/Dingjun/Hanzhong/Jing defense/Fan Castle/Han River/Fan siege/Jing rear camp states, campaign timeline state, and camp save state
|
||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
1. Build the Jing Province rear-crisis follow-up, using Fan Castle's pressure, Wu's river scouts, and the first signs of rear-line collapse as the next campaign tension
|
1. Build the Jing Province rear-collapse follow-up, using Lu Meng's infiltration, Mi Fang/Fu Shiren's wavering, and Guan Yu's overextended Fan Castle front as the next campaign tension
|
||||||
2. Expand Fan Castle aftermath events, including rear guard assignments, river signal choices, siege fatigue, and supply decisions that affect sortie recommendations
|
2. Expand Jing rear-crisis aftermath events, including warehouse trust, river rumor choices, officer loyalty checks, and supply decisions that affect sortie recommendations
|
||||||
3. Expand sortie selection into richer pre-battle officer planning, including explicit reserve drills, class practice, and bond-focused camp assignments
|
3. Expand sortie selection into richer pre-battle officer planning, including explicit reserve drills, class practice, and bond-focused camp assignments
|
||||||
4. Add a dedicated treasure/equipment management view so players can compare special effects and growth
|
4. Add a dedicated treasure/equipment management view so players can compare special effects and growth
|
||||||
5. Keep expanding scenarios through the long campaign instead of treating the current slice as an ending
|
5. Keep expanding scenarios through the long campaign instead of treating the current slice as an ending
|
||||||
|
|||||||
@@ -1736,7 +1736,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
progressTabState?.activeTab !== 'progress' ||
|
progressTabState?.activeTab !== 'progress' ||
|
||||||
progressTabState.campaignProgress?.completedKnown !== 17 ||
|
progressTabState.campaignProgress?.completedKnown !== 17 ||
|
||||||
progressTabState.campaignProgress?.totalKnown !== 41 ||
|
progressTabState.campaignProgress?.totalKnown !== 42 ||
|
||||||
progressTabState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
progressTabState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
||||||
progressTabState.campaignProgress?.latestBattleTitle !== '융중 방문로' ||
|
progressTabState.campaignProgress?.latestBattleTitle !== '융중 방문로' ||
|
||||||
progressTabState.campaignProgress?.nextBattleTitle !== '박망파 매복전'
|
progressTabState.campaignProgress?.nextBattleTitle !== '박망파 매복전'
|
||||||
@@ -1888,7 +1888,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postBowangProgressState?.activeTab !== 'progress' ||
|
postBowangProgressState?.activeTab !== 'progress' ||
|
||||||
postBowangProgressState.campaignProgress?.completedKnown !== 18 ||
|
postBowangProgressState.campaignProgress?.completedKnown !== 18 ||
|
||||||
postBowangProgressState.campaignProgress?.totalKnown !== 41 ||
|
postBowangProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postBowangProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
postBowangProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
||||||
postBowangProgressState.campaignProgress?.latestBattleTitle !== '박망파 매복전' ||
|
postBowangProgressState.campaignProgress?.latestBattleTitle !== '박망파 매복전' ||
|
||||||
postBowangProgressState.campaignProgress?.nextBattleTitle !== '장판파 피난로'
|
postBowangProgressState.campaignProgress?.nextBattleTitle !== '장판파 피난로'
|
||||||
@@ -2026,7 +2026,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postChangbanProgressState?.activeTab !== 'progress' ||
|
postChangbanProgressState?.activeTab !== 'progress' ||
|
||||||
postChangbanProgressState.campaignProgress?.completedKnown !== 19 ||
|
postChangbanProgressState.campaignProgress?.completedKnown !== 19 ||
|
||||||
postChangbanProgressState.campaignProgress?.totalKnown !== 41 ||
|
postChangbanProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postChangbanProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
postChangbanProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
||||||
postChangbanProgressState.campaignProgress?.latestBattleTitle !== '장판파 피난로' ||
|
postChangbanProgressState.campaignProgress?.latestBattleTitle !== '장판파 피난로' ||
|
||||||
postChangbanProgressState.campaignProgress?.nextBattleTitle !== '강동 사절로'
|
postChangbanProgressState.campaignProgress?.nextBattleTitle !== '강동 사절로'
|
||||||
@@ -2164,7 +2164,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postJiangdongProgressState?.activeTab !== 'progress' ||
|
postJiangdongProgressState?.activeTab !== 'progress' ||
|
||||||
postJiangdongProgressState.campaignProgress?.completedKnown !== 20 ||
|
postJiangdongProgressState.campaignProgress?.completedKnown !== 20 ||
|
||||||
postJiangdongProgressState.campaignProgress?.totalKnown !== 41 ||
|
postJiangdongProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postJiangdongProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
postJiangdongProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
||||||
postJiangdongProgressState.campaignProgress?.latestBattleTitle !== '강동 사절로' ||
|
postJiangdongProgressState.campaignProgress?.latestBattleTitle !== '강동 사절로' ||
|
||||||
postJiangdongProgressState.campaignProgress?.nextBattleTitle !== '적벽 전초전'
|
postJiangdongProgressState.campaignProgress?.nextBattleTitle !== '적벽 전초전'
|
||||||
@@ -2304,7 +2304,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postRedCliffsProgressState?.activeTab !== 'progress' ||
|
postRedCliffsProgressState?.activeTab !== 'progress' ||
|
||||||
postRedCliffsProgressState.campaignProgress?.completedKnown !== 21 ||
|
postRedCliffsProgressState.campaignProgress?.completedKnown !== 21 ||
|
||||||
postRedCliffsProgressState.campaignProgress?.totalKnown !== 41 ||
|
postRedCliffsProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postRedCliffsProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
postRedCliffsProgressState.campaignProgress?.activeChapter?.title !== '적벽대전' ||
|
||||||
postRedCliffsProgressState.campaignProgress?.latestBattleTitle !== '적벽 전초전' ||
|
postRedCliffsProgressState.campaignProgress?.latestBattleTitle !== '적벽 전초전' ||
|
||||||
postRedCliffsProgressState.campaignProgress?.nextBattleTitle !== '적벽 화공전'
|
postRedCliffsProgressState.campaignProgress?.nextBattleTitle !== '적벽 화공전'
|
||||||
@@ -2444,7 +2444,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postFireAttackProgressState?.activeTab !== 'progress' ||
|
postFireAttackProgressState?.activeTab !== 'progress' ||
|
||||||
postFireAttackProgressState.campaignProgress?.completedKnown !== 22 ||
|
postFireAttackProgressState.campaignProgress?.completedKnown !== 22 ||
|
||||||
postFireAttackProgressState.campaignProgress?.totalKnown !== 41 ||
|
postFireAttackProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postFireAttackProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postFireAttackProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postFireAttackProgressState.campaignProgress?.latestBattleTitle !== '적벽 화공전' ||
|
postFireAttackProgressState.campaignProgress?.latestBattleTitle !== '적벽 화공전' ||
|
||||||
postFireAttackProgressState.campaignProgress?.nextBattleTitle !== '형주 남부 진입전'
|
postFireAttackProgressState.campaignProgress?.nextBattleTitle !== '형주 남부 진입전'
|
||||||
@@ -2587,7 +2587,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postJingzhouProgressState?.activeTab !== 'progress' ||
|
postJingzhouProgressState?.activeTab !== 'progress' ||
|
||||||
postJingzhouProgressState.campaignProgress?.completedKnown !== 23 ||
|
postJingzhouProgressState.campaignProgress?.completedKnown !== 23 ||
|
||||||
postJingzhouProgressState.campaignProgress?.totalKnown !== 41 ||
|
postJingzhouProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postJingzhouProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postJingzhouProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postJingzhouProgressState.campaignProgress?.latestBattleTitle !== '형주 남부 진입전' ||
|
postJingzhouProgressState.campaignProgress?.latestBattleTitle !== '형주 남부 진입전' ||
|
||||||
postJingzhouProgressState.campaignProgress?.nextBattleTitle !== '계양 설득전'
|
postJingzhouProgressState.campaignProgress?.nextBattleTitle !== '계양 설득전'
|
||||||
@@ -2729,7 +2729,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postGuiyangProgressState?.activeTab !== 'progress' ||
|
postGuiyangProgressState?.activeTab !== 'progress' ||
|
||||||
postGuiyangProgressState.campaignProgress?.completedKnown !== 24 ||
|
postGuiyangProgressState.campaignProgress?.completedKnown !== 24 ||
|
||||||
postGuiyangProgressState.campaignProgress?.totalKnown !== 41 ||
|
postGuiyangProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postGuiyangProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postGuiyangProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postGuiyangProgressState.campaignProgress?.latestBattleTitle !== '계양 설득전' ||
|
postGuiyangProgressState.campaignProgress?.latestBattleTitle !== '계양 설득전' ||
|
||||||
postGuiyangProgressState.campaignProgress?.nextBattleTitle !== '무릉 산길 확보전'
|
postGuiyangProgressState.campaignProgress?.nextBattleTitle !== '무릉 산길 확보전'
|
||||||
@@ -2872,7 +2872,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postWulingProgressState?.activeTab !== 'progress' ||
|
postWulingProgressState?.activeTab !== 'progress' ||
|
||||||
postWulingProgressState.campaignProgress?.completedKnown !== 25 ||
|
postWulingProgressState.campaignProgress?.completedKnown !== 25 ||
|
||||||
postWulingProgressState.campaignProgress?.totalKnown !== 41 ||
|
postWulingProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postWulingProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postWulingProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postWulingProgressState.campaignProgress?.latestBattleTitle !== '무릉 산길 확보전' ||
|
postWulingProgressState.campaignProgress?.latestBattleTitle !== '무릉 산길 확보전' ||
|
||||||
postWulingProgressState.campaignProgress?.nextBattleTitle !== '장사 노장 대면전'
|
postWulingProgressState.campaignProgress?.nextBattleTitle !== '장사 노장 대면전'
|
||||||
@@ -3021,7 +3021,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postChangshaProgressState?.activeTab !== 'progress' ||
|
postChangshaProgressState?.activeTab !== 'progress' ||
|
||||||
postChangshaProgressState.campaignProgress?.completedKnown !== 26 ||
|
postChangshaProgressState.campaignProgress?.completedKnown !== 26 ||
|
||||||
postChangshaProgressState.campaignProgress?.totalKnown !== 41 ||
|
postChangshaProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postChangshaProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postChangshaProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postChangshaProgressState.campaignProgress?.latestBattleTitle !== '장사 노장 대면전' ||
|
postChangshaProgressState.campaignProgress?.latestBattleTitle !== '장사 노장 대면전' ||
|
||||||
postChangshaProgressState.campaignProgress?.nextBattleTitle !== '익주 원군로'
|
postChangshaProgressState.campaignProgress?.nextBattleTitle !== '익주 원군로'
|
||||||
@@ -3166,7 +3166,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postYizhouProgressState?.activeTab !== 'progress' ||
|
postYizhouProgressState?.activeTab !== 'progress' ||
|
||||||
postYizhouProgressState.campaignProgress?.completedKnown !== 27 ||
|
postYizhouProgressState.campaignProgress?.completedKnown !== 27 ||
|
||||||
postYizhouProgressState.campaignProgress?.totalKnown !== 41 ||
|
postYizhouProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postYizhouProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postYizhouProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postYizhouProgressState.campaignProgress?.latestBattleTitle !== '익주 원군로' ||
|
postYizhouProgressState.campaignProgress?.latestBattleTitle !== '익주 원군로' ||
|
||||||
postYizhouProgressState.campaignProgress?.nextBattleTitle !== '부수관 진입전'
|
postYizhouProgressState.campaignProgress?.nextBattleTitle !== '부수관 진입전'
|
||||||
@@ -3313,7 +3313,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postFuPassProgressState?.activeTab !== 'progress' ||
|
postFuPassProgressState?.activeTab !== 'progress' ||
|
||||||
postFuPassProgressState.campaignProgress?.completedKnown !== 28 ||
|
postFuPassProgressState.campaignProgress?.completedKnown !== 28 ||
|
||||||
postFuPassProgressState.campaignProgress?.totalKnown !== 41 ||
|
postFuPassProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postFuPassProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postFuPassProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postFuPassProgressState.campaignProgress?.latestBattleTitle !== '부수관 진입전' ||
|
postFuPassProgressState.campaignProgress?.latestBattleTitle !== '부수관 진입전' ||
|
||||||
postFuPassProgressState.campaignProgress?.nextBattleTitle !== '낙성 외곽전'
|
postFuPassProgressState.campaignProgress?.nextBattleTitle !== '낙성 외곽전'
|
||||||
@@ -3462,7 +3462,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postLuoProgressState?.activeTab !== 'progress' ||
|
postLuoProgressState?.activeTab !== 'progress' ||
|
||||||
postLuoProgressState.campaignProgress?.completedKnown !== 29 ||
|
postLuoProgressState.campaignProgress?.completedKnown !== 29 ||
|
||||||
postLuoProgressState.campaignProgress?.totalKnown !== 41 ||
|
postLuoProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postLuoProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postLuoProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postLuoProgressState.campaignProgress?.latestBattleTitle !== '낙성 외곽전' ||
|
postLuoProgressState.campaignProgress?.latestBattleTitle !== '낙성 외곽전' ||
|
||||||
postLuoProgressState.campaignProgress?.nextBattleTitle !== '낙봉파 매복전'
|
postLuoProgressState.campaignProgress?.nextBattleTitle !== '낙봉파 매복전'
|
||||||
@@ -3608,7 +3608,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postLuofengProgressState?.activeTab !== 'progress' ||
|
postLuofengProgressState?.activeTab !== 'progress' ||
|
||||||
postLuofengProgressState.campaignProgress?.completedKnown !== 30 ||
|
postLuofengProgressState.campaignProgress?.completedKnown !== 30 ||
|
||||||
postLuofengProgressState.campaignProgress?.totalKnown !== 41 ||
|
postLuofengProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postLuofengProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postLuofengProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postLuofengProgressState.campaignProgress?.latestBattleTitle !== '낙봉파 매복전' ||
|
postLuofengProgressState.campaignProgress?.latestBattleTitle !== '낙봉파 매복전' ||
|
||||||
postLuofengProgressState.campaignProgress?.nextBattleTitle !== '낙성 본성 공략'
|
postLuofengProgressState.campaignProgress?.nextBattleTitle !== '낙성 본성 공략'
|
||||||
@@ -3760,7 +3760,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postLuoMainProgressState?.activeTab !== 'progress' ||
|
postLuoMainProgressState?.activeTab !== 'progress' ||
|
||||||
postLuoMainProgressState.campaignProgress?.completedKnown !== 31 ||
|
postLuoMainProgressState.campaignProgress?.completedKnown !== 31 ||
|
||||||
postLuoMainProgressState.campaignProgress?.totalKnown !== 41 ||
|
postLuoMainProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postLuoMainProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postLuoMainProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postLuoMainProgressState.campaignProgress?.latestBattleTitle !== '낙성 본성 공략' ||
|
postLuoMainProgressState.campaignProgress?.latestBattleTitle !== '낙성 본성 공략' ||
|
||||||
postLuoMainProgressState.campaignProgress?.nextBattleTitle !== '면죽관 압박전'
|
postLuoMainProgressState.campaignProgress?.nextBattleTitle !== '면죽관 압박전'
|
||||||
@@ -3913,7 +3913,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postMianzhuProgressState?.activeTab !== 'progress' ||
|
postMianzhuProgressState?.activeTab !== 'progress' ||
|
||||||
postMianzhuProgressState.campaignProgress?.completedKnown !== 32 ||
|
postMianzhuProgressState.campaignProgress?.completedKnown !== 32 ||
|
||||||
postMianzhuProgressState.campaignProgress?.totalKnown !== 41 ||
|
postMianzhuProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postMianzhuProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
postMianzhuProgressState.campaignProgress?.activeChapter?.title !== '형주·익주 확보' ||
|
||||||
postMianzhuProgressState.campaignProgress?.latestBattleTitle !== '면죽관 압박전' ||
|
postMianzhuProgressState.campaignProgress?.latestBattleTitle !== '면죽관 압박전' ||
|
||||||
postMianzhuProgressState.campaignProgress?.nextBattleTitle !== '성도 항복 권고전'
|
postMianzhuProgressState.campaignProgress?.nextBattleTitle !== '성도 항복 권고전'
|
||||||
@@ -4067,7 +4067,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postChengduProgressState?.activeTab !== 'progress' ||
|
postChengduProgressState?.activeTab !== 'progress' ||
|
||||||
postChengduProgressState.campaignProgress?.completedKnown !== 33 ||
|
postChengduProgressState.campaignProgress?.completedKnown !== 33 ||
|
||||||
postChengduProgressState.campaignProgress?.totalKnown !== 41 ||
|
postChengduProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postChengduProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
postChengduProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
||||||
postChengduProgressState.campaignProgress?.latestBattleTitle !== '성도 항복 권고전' ||
|
postChengduProgressState.campaignProgress?.latestBattleTitle !== '성도 항복 권고전' ||
|
||||||
postChengduProgressState.campaignProgress?.nextBattleTitle !== '가맹관 마초 대면전'
|
postChengduProgressState.campaignProgress?.nextBattleTitle !== '가맹관 마초 대면전'
|
||||||
@@ -4222,7 +4222,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postJiamengProgressState?.activeTab !== 'progress' ||
|
postJiamengProgressState?.activeTab !== 'progress' ||
|
||||||
postJiamengProgressState.campaignProgress?.completedKnown !== 34 ||
|
postJiamengProgressState.campaignProgress?.completedKnown !== 34 ||
|
||||||
postJiamengProgressState.campaignProgress?.totalKnown !== 41 ||
|
postJiamengProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postJiamengProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
postJiamengProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
||||||
postJiamengProgressState.campaignProgress?.latestBattleTitle !== '가맹관 마초 대면전' ||
|
postJiamengProgressState.campaignProgress?.latestBattleTitle !== '가맹관 마초 대면전' ||
|
||||||
postJiamengProgressState.campaignProgress?.nextBattleTitle !== '양평관 정찰전'
|
postJiamengProgressState.campaignProgress?.nextBattleTitle !== '양평관 정찰전'
|
||||||
@@ -4378,7 +4378,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postYangpingProgressState?.activeTab !== 'progress' ||
|
postYangpingProgressState?.activeTab !== 'progress' ||
|
||||||
postYangpingProgressState.campaignProgress?.completedKnown !== 35 ||
|
postYangpingProgressState.campaignProgress?.completedKnown !== 35 ||
|
||||||
postYangpingProgressState.campaignProgress?.totalKnown !== 41 ||
|
postYangpingProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postYangpingProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
postYangpingProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
||||||
postYangpingProgressState.campaignProgress?.latestBattleTitle !== '양평관 정찰전' ||
|
postYangpingProgressState.campaignProgress?.latestBattleTitle !== '양평관 정찰전' ||
|
||||||
postYangpingProgressState.campaignProgress?.nextBattleTitle !== '정군산 전초전'
|
postYangpingProgressState.campaignProgress?.nextBattleTitle !== '정군산 전초전'
|
||||||
@@ -4535,7 +4535,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postDingjunProgressState?.activeTab !== 'progress' ||
|
postDingjunProgressState?.activeTab !== 'progress' ||
|
||||||
postDingjunProgressState.campaignProgress?.completedKnown !== 36 ||
|
postDingjunProgressState.campaignProgress?.completedKnown !== 36 ||
|
||||||
postDingjunProgressState.campaignProgress?.totalKnown !== 41 ||
|
postDingjunProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postDingjunProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
postDingjunProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
||||||
postDingjunProgressState.campaignProgress?.latestBattleTitle !== '정군산 전초전' ||
|
postDingjunProgressState.campaignProgress?.latestBattleTitle !== '정군산 전초전' ||
|
||||||
postDingjunProgressState.campaignProgress?.nextBattleTitle !== '한중 결전'
|
postDingjunProgressState.campaignProgress?.nextBattleTitle !== '한중 결전'
|
||||||
@@ -4688,7 +4688,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postHanzhongProgressState?.activeTab !== 'progress' ||
|
postHanzhongProgressState?.activeTab !== 'progress' ||
|
||||||
postHanzhongProgressState.campaignProgress?.completedKnown !== 37 ||
|
postHanzhongProgressState.campaignProgress?.completedKnown !== 37 ||
|
||||||
postHanzhongProgressState.campaignProgress?.totalKnown !== 41 ||
|
postHanzhongProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postHanzhongProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
postHanzhongProgressState.campaignProgress?.activeChapter?.title !== '촉한 건국' ||
|
||||||
postHanzhongProgressState.campaignProgress?.latestBattleTitle !== '한중 결전' ||
|
postHanzhongProgressState.campaignProgress?.latestBattleTitle !== '한중 결전' ||
|
||||||
postHanzhongProgressState.campaignProgress?.nextBattleTitle !== '한중왕 즉위 준비'
|
postHanzhongProgressState.campaignProgress?.nextBattleTitle !== '한중왕 즉위 준비'
|
||||||
@@ -4749,7 +4749,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postKingCouncilProgressState?.activeTab !== 'progress' ||
|
postKingCouncilProgressState?.activeTab !== 'progress' ||
|
||||||
postKingCouncilProgressState.campaignProgress?.completedKnown !== 37 ||
|
postKingCouncilProgressState.campaignProgress?.completedKnown !== 37 ||
|
||||||
postKingCouncilProgressState.campaignProgress?.totalKnown !== 41 ||
|
postKingCouncilProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postKingCouncilProgressState.campaignProgress?.latestBattleTitle !== '한중 결전' ||
|
postKingCouncilProgressState.campaignProgress?.latestBattleTitle !== '한중 결전' ||
|
||||||
postKingCouncilProgressState.campaignProgress?.nextBattleTitle !== '촉한 건국 선포'
|
postKingCouncilProgressState.campaignProgress?.nextBattleTitle !== '촉한 건국 선포'
|
||||||
) {
|
) {
|
||||||
@@ -4809,7 +4809,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postFoundationProgressState?.activeTab !== 'progress' ||
|
postFoundationProgressState?.activeTab !== 'progress' ||
|
||||||
postFoundationProgressState.campaignProgress?.completedKnown !== 37 ||
|
postFoundationProgressState.campaignProgress?.completedKnown !== 37 ||
|
||||||
postFoundationProgressState.campaignProgress?.totalKnown !== 41 ||
|
postFoundationProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postFoundationProgressState.campaignProgress?.latestBattleTitle !== '한중 결전' ||
|
postFoundationProgressState.campaignProgress?.latestBattleTitle !== '한중 결전' ||
|
||||||
postFoundationProgressState.campaignProgress?.nextBattleTitle !== '형주 방위 전초전'
|
postFoundationProgressState.campaignProgress?.nextBattleTitle !== '형주 방위 전초전'
|
||||||
) {
|
) {
|
||||||
@@ -4960,7 +4960,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postJingDefenseProgressState?.activeTab !== 'progress' ||
|
postJingDefenseProgressState?.activeTab !== 'progress' ||
|
||||||
postJingDefenseProgressState.campaignProgress?.completedKnown !== 38 ||
|
postJingDefenseProgressState.campaignProgress?.completedKnown !== 38 ||
|
||||||
postJingDefenseProgressState.campaignProgress?.totalKnown !== 41 ||
|
postJingDefenseProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postJingDefenseProgressState.campaignProgress?.latestBattleTitle !== '형주 방위 전초전' ||
|
postJingDefenseProgressState.campaignProgress?.latestBattleTitle !== '형주 방위 전초전' ||
|
||||||
postJingDefenseProgressState.campaignProgress?.nextBattleTitle !== '번성 외곽 압박전'
|
postJingDefenseProgressState.campaignProgress?.nextBattleTitle !== '번성 외곽 압박전'
|
||||||
) {
|
) {
|
||||||
@@ -5113,7 +5113,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postFanCastleProgressState?.activeTab !== 'progress' ||
|
postFanCastleProgressState?.activeTab !== 'progress' ||
|
||||||
postFanCastleProgressState.campaignProgress?.completedKnown !== 39 ||
|
postFanCastleProgressState.campaignProgress?.completedKnown !== 39 ||
|
||||||
postFanCastleProgressState.campaignProgress?.totalKnown !== 41 ||
|
postFanCastleProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postFanCastleProgressState.campaignProgress?.latestBattleTitle !== '번성 외곽 압박전' ||
|
postFanCastleProgressState.campaignProgress?.latestBattleTitle !== '번성 외곽 압박전' ||
|
||||||
postFanCastleProgressState.campaignProgress?.nextBattleTitle !== '한수 수공'
|
postFanCastleProgressState.campaignProgress?.nextBattleTitle !== '한수 수공'
|
||||||
) {
|
) {
|
||||||
@@ -5267,7 +5267,7 @@ try {
|
|||||||
if (
|
if (
|
||||||
postHanRiverProgressState?.activeTab !== 'progress' ||
|
postHanRiverProgressState?.activeTab !== 'progress' ||
|
||||||
postHanRiverProgressState.campaignProgress?.completedKnown !== 40 ||
|
postHanRiverProgressState.campaignProgress?.completedKnown !== 40 ||
|
||||||
postHanRiverProgressState.campaignProgress?.totalKnown !== 41 ||
|
postHanRiverProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postHanRiverProgressState.campaignProgress?.latestBattleTitle !== '한수 수공' ||
|
postHanRiverProgressState.campaignProgress?.latestBattleTitle !== '한수 수공' ||
|
||||||
postHanRiverProgressState.campaignProgress?.nextBattleTitle !== '번성 공성전'
|
postHanRiverProgressState.campaignProgress?.nextBattleTitle !== '번성 공성전'
|
||||||
) {
|
) {
|
||||||
@@ -5421,14 +5421,168 @@ try {
|
|||||||
if (
|
if (
|
||||||
postFanSiegeProgressState?.activeTab !== 'progress' ||
|
postFanSiegeProgressState?.activeTab !== 'progress' ||
|
||||||
postFanSiegeProgressState.campaignProgress?.completedKnown !== 41 ||
|
postFanSiegeProgressState.campaignProgress?.completedKnown !== 41 ||
|
||||||
postFanSiegeProgressState.campaignProgress?.totalKnown !== 41 ||
|
postFanSiegeProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
postFanSiegeProgressState.campaignProgress?.latestBattleTitle !== '번성 공성전' ||
|
postFanSiegeProgressState.campaignProgress?.latestBattleTitle !== '번성 공성전' ||
|
||||||
postFanSiegeProgressState.campaignProgress?.nextBattleTitle !== '준비 중'
|
postFanSiegeProgressState.campaignProgress?.nextBattleTitle !== '강릉 나루 경계전'
|
||||||
) {
|
) {
|
||||||
throw new Error(`Expected post-Fan Castle siege progress tab to complete the forty-first battle and leave Jing Province crisis as the next prepared slice: ${JSON.stringify(postFanSiegeProgressState?.campaignProgress)}`);
|
throw new Error(`Expected post-Fan Castle siege progress tab to complete the forty-first battle and point to Jing rear crisis: ${JSON.stringify(postFanSiegeProgressState?.campaignProgress)}`);
|
||||||
}
|
}
|
||||||
await page.screenshot({ path: 'dist/verification-post-fan-siege-progress.png', fullPage: true });
|
await page.screenshot({ path: 'dist/verification-post-fan-siege-progress.png', fullPage: true });
|
||||||
|
|
||||||
|
await page.mouse.click(1120, 38);
|
||||||
|
await page.waitForTimeout(180);
|
||||||
|
const jingRearSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||||
|
if (
|
||||||
|
!jingRearSortieState?.sortieVisible ||
|
||||||
|
jingRearSortieState.campaign?.step !== 'forty-first-camp' ||
|
||||||
|
jingRearSortieState.sortiePlan?.objectiveLine !== '강릉 나루 경계전 · 여몽 정찰대 격퇴' ||
|
||||||
|
jingRearSortieState.sortiePlan?.maxCount !== 7 ||
|
||||||
|
jingRearSortieState.sortiePlan?.recommendedTotal !== 7 ||
|
||||||
|
!jingRearSortieState.sortieRoster?.some((unit) => unit.id === 'guan-yu' && unit.selected && unit.required)
|
||||||
|
) {
|
||||||
|
throw new Error(`Expected Jing rear sortie prep to lock Guan Yu and expose a seven-officer rear-guard choice: ${JSON.stringify(jingRearSortieState)}`);
|
||||||
|
}
|
||||||
|
assertSortieTacticalRoster(jingRearSortieState, [
|
||||||
|
'liu-bei',
|
||||||
|
'guan-yu',
|
||||||
|
'zhang-fei',
|
||||||
|
'jian-yong',
|
||||||
|
'mi-zhu',
|
||||||
|
'sun-qian',
|
||||||
|
'zhao-yun',
|
||||||
|
'zhuge-liang',
|
||||||
|
'ma-liang',
|
||||||
|
'yi-ji',
|
||||||
|
'gong-zhi',
|
||||||
|
'huang-zhong',
|
||||||
|
'wei-yan',
|
||||||
|
'pang-tong',
|
||||||
|
'fa-zheng',
|
||||||
|
'wu-yi',
|
||||||
|
'yan-yan',
|
||||||
|
'li-yan',
|
||||||
|
'huang-quan',
|
||||||
|
'ma-chao',
|
||||||
|
'ma-dai',
|
||||||
|
'wang-ping'
|
||||||
|
]);
|
||||||
|
|
||||||
|
const jingRearPriorityUnits = ['ma-liang', 'mi-zhu', 'zhao-yun', 'huang-quan', 'wang-ping'];
|
||||||
|
for (const unitId of jingRearPriorityUnits) {
|
||||||
|
const currentSortieState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||||
|
if (!currentSortieState.sortieRoster?.some((unit) => unit.id === unitId && unit.selected)) {
|
||||||
|
const removable = currentSortieState.sortieRoster?.find(
|
||||||
|
(unit) => unit.selected && !unit.required && !jingRearPriorityUnits.includes(unit.id)
|
||||||
|
);
|
||||||
|
if (removable) {
|
||||||
|
await clickSortieRosterUnit(page, removable.id);
|
||||||
|
}
|
||||||
|
await clickSortieRosterUnit(page, unitId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const jingRearSortieReadyState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||||
|
if (
|
||||||
|
!jingRearPriorityUnits.every((unitId) =>
|
||||||
|
jingRearSortieReadyState.sortieRoster?.some((unit) => unit.id === unitId && unit.selected)
|
||||||
|
) ||
|
||||||
|
!jingRearSortieReadyState.sortieRoster?.some((unit) => unit.id === 'liu-bei' && unit.selected && unit.required) ||
|
||||||
|
!jingRearSortieReadyState.sortieRoster?.some((unit) => unit.id === 'guan-yu' && unit.selected && unit.required) ||
|
||||||
|
jingRearSortieReadyState.sortiePlan?.selectedCount !== 7 ||
|
||||||
|
jingRearSortieReadyState.sortiePlan?.recommendedSelectedCount < 7
|
||||||
|
) {
|
||||||
|
throw new Error(`Expected Jing rear sortie to deploy Liu Bei, Guan Yu, Ma Liang, Mi Zhu, Zhao Yun, Huang Quan, and Wang Ping: ${JSON.stringify(jingRearSortieReadyState)}`);
|
||||||
|
}
|
||||||
|
await page.screenshot({ path: 'dist/verification-jing-rear-sortie.png', fullPage: true });
|
||||||
|
|
||||||
|
await page.mouse.click(1068, 646);
|
||||||
|
await page.waitForFunction(() => {
|
||||||
|
const activeScenes = window.__HEROS_DEBUG__?.activeScenes() ?? [];
|
||||||
|
return activeScenes.includes('StoryScene');
|
||||||
|
});
|
||||||
|
await page.screenshot({ path: 'dist/verification-jing-rear-story.png', fullPage: true });
|
||||||
|
|
||||||
|
for (let i = 0; i < 45; i += 1) {
|
||||||
|
const enteredFortySecondBattle = await page.evaluate(() => {
|
||||||
|
const state = window.__HEROS_DEBUG__?.battle();
|
||||||
|
return state?.scene === 'BattleScene' && state?.battleId === 'forty-second-battle-jing-rear-crisis';
|
||||||
|
});
|
||||||
|
if (enteredFortySecondBattle) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await page.keyboard.press('Space');
|
||||||
|
await page.waitForTimeout(320);
|
||||||
|
}
|
||||||
|
await page.waitForFunction(() => {
|
||||||
|
const state = window.__HEROS_DEBUG__?.battle();
|
||||||
|
return state?.scene === 'BattleScene' && state?.battleId === 'forty-second-battle-jing-rear-crisis' && state?.battleOutcome === null && state?.phase === 'idle';
|
||||||
|
});
|
||||||
|
await page.screenshot({ path: 'dist/verification-forty-second-battle.png', fullPage: true });
|
||||||
|
|
||||||
|
const fortySecondBattleState = await page.evaluate(() => window.__HEROS_DEBUG__?.battle());
|
||||||
|
const fortySecondEnemies = fortySecondBattleState.units.filter((unit) => unit.faction === 'enemy');
|
||||||
|
const fortySecondAllies = fortySecondBattleState.units.filter((unit) => unit.faction === 'ally');
|
||||||
|
const fortySecondEnemyBehaviors = new Set(fortySecondEnemies.map((unit) => unit.ai));
|
||||||
|
if (
|
||||||
|
fortySecondBattleState.camera?.mapWidth !== 84 ||
|
||||||
|
fortySecondBattleState.camera?.mapHeight !== 66 ||
|
||||||
|
fortySecondBattleState.victoryConditionLabel !== '여몽 정찰대 격퇴' ||
|
||||||
|
fortySecondEnemies.length < 35 ||
|
||||||
|
!fortySecondEnemyBehaviors.has('aggressive') ||
|
||||||
|
!fortySecondEnemyBehaviors.has('guard') ||
|
||||||
|
!fortySecondEnemyBehaviors.has('hold') ||
|
||||||
|
!fortySecondEnemies.some((unit) => unit.id === 'jing-rear-leader-lu-meng') ||
|
||||||
|
!fortySecondEnemies.some((unit) => unit.id === 'jing-rear-officer-lu-xun') ||
|
||||||
|
!fortySecondEnemies.some((unit) => unit.id === 'jing-rear-officer-mi-fang') ||
|
||||||
|
!fortySecondAllies.some((unit) => unit.id === 'guan-yu') ||
|
||||||
|
!fortySecondAllies.some((unit) => unit.id === 'ma-liang') ||
|
||||||
|
!fortySecondAllies.some((unit) => unit.id === 'mi-zhu') ||
|
||||||
|
!fortySecondAllies.some((unit) => unit.id === 'huang-quan') ||
|
||||||
|
!fortySecondAllies.some((unit) => unit.id === 'wang-ping')
|
||||||
|
) {
|
||||||
|
throw new Error(`Expected forty-second battle to use Jing rear map, Lu Meng objective, selected rear-guard officers, and mixed Wu AI: ${JSON.stringify(fortySecondBattleState)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.evaluate(() => window.__HEROS_DEBUG__?.forceBattleOutcome('victory'));
|
||||||
|
await page.waitForFunction(() => {
|
||||||
|
const state = window.__HEROS_DEBUG__?.battle();
|
||||||
|
return state?.battleOutcome === 'victory' && state?.phase === 'resolved' && state?.resultVisible === true;
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.mouse.click(738, 642);
|
||||||
|
await page.waitForFunction(() => {
|
||||||
|
const activeScenes = window.__HEROS_DEBUG__?.activeScenes() ?? [];
|
||||||
|
return activeScenes.includes('CampScene');
|
||||||
|
});
|
||||||
|
|
||||||
|
const fortySecondCampState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||||
|
if (
|
||||||
|
fortySecondCampState?.campBattleId !== 'forty-second-battle-jing-rear-crisis' ||
|
||||||
|
fortySecondCampState.campTitle !== '강릉 나루 경계전 후 군영' ||
|
||||||
|
fortySecondCampState.availableDialogueIds?.length !== 3 ||
|
||||||
|
!fortySecondCampState.availableDialogueIds.every((id) => id.endsWith('jing-rear')) ||
|
||||||
|
fortySecondCampState.availableVisitIds?.length !== 2 ||
|
||||||
|
!fortySecondCampState.availableVisitIds.every((id) => id.includes('jing-rear')) ||
|
||||||
|
fortySecondCampState.rosterCollection?.total < 22
|
||||||
|
) {
|
||||||
|
throw new Error(`Expected forty-second camp to expose Jing rear dialogue/visit sets and preserve the full officer roster: ${JSON.stringify(fortySecondCampState)}`);
|
||||||
|
}
|
||||||
|
await page.screenshot({ path: 'dist/verification-jing-rear-camp.png', fullPage: true });
|
||||||
|
|
||||||
|
await page.mouse.click(966, 38);
|
||||||
|
await page.waitForTimeout(180);
|
||||||
|
const postJingRearProgressState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||||
|
if (
|
||||||
|
postJingRearProgressState?.activeTab !== 'progress' ||
|
||||||
|
postJingRearProgressState.campaignProgress?.completedKnown !== 42 ||
|
||||||
|
postJingRearProgressState.campaignProgress?.totalKnown !== 42 ||
|
||||||
|
postJingRearProgressState.campaignProgress?.latestBattleTitle !== '강릉 나루 경계전' ||
|
||||||
|
postJingRearProgressState.campaignProgress?.nextBattleTitle !== '준비 중'
|
||||||
|
) {
|
||||||
|
throw new Error(`Expected post-Jing rear progress tab to complete the forty-second battle and leave rear collapse as the next prepared slice: ${JSON.stringify(postJingRearProgressState?.campaignProgress)}`);
|
||||||
|
}
|
||||||
|
await page.screenshot({ path: 'dist/verification-post-jing-rear-progress.png', fullPage: true });
|
||||||
|
|
||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const game = window.__HEROS_GAME__;
|
const game = window.__HEROS_GAME__;
|
||||||
game?.scene.stop('CampScene');
|
game?.scene.stop('CampScene');
|
||||||
@@ -5461,10 +5615,10 @@ try {
|
|||||||
camp: window.__HEROS_DEBUG__?.camp?.() ?? null
|
camp: window.__HEROS_DEBUG__?.camp?.() ?? null
|
||||||
}));
|
}));
|
||||||
if (!titleContinueState.activeScenes.includes('CampScene')) {
|
if (!titleContinueState.activeScenes.includes('CampScene')) {
|
||||||
throw new Error(`Expected title continue to reopen the latest camp after Fan Castle siege: ${JSON.stringify(titleContinueState)}`);
|
throw new Error(`Expected title continue to reopen the latest camp after Jing rear crisis: ${JSON.stringify(titleContinueState)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Verified title-to-forty-first-battle flow, recruited officer sortie selection, Ma Liang, Yi Ji, Gong Zhi, Huang Zhong, Wei Yan, Pang Tong, Fa Zheng, Wu Yi, Yan Yan, Li Yan, Huang Quan, Ma Chao, Ma Dai, Wang Ping joins, Luofeng, Luo main gate, Mianzhu, Chengdu surrender, Jiameng, Yangping, Dingjun, Hanzhong decisive battle, King of Hanzhong council, Shu-Han foundation state, Jing Province defense vanguard, Fan Castle vanguard, Han River flood, and Fan Castle siege state at ${targetUrl}`);
|
console.log(`Verified title-to-forty-second-battle flow, recruited officer sortie selection, Ma Liang, Yi Ji, Gong Zhi, Huang Zhong, Wei Yan, Pang Tong, Fa Zheng, Wu Yi, Yan Yan, Li Yan, Huang Quan, Ma Chao, Ma Dai, Wang Ping joins, Luofeng, Luo main gate, Mianzhu, Chengdu surrender, Jiameng, Yangping, Dingjun, Hanzhong decisive battle, King of Hanzhong council, Shu-Han foundation state, Jing Province defense vanguard, Fan Castle vanguard, Han River flood, Fan Castle siege, and Jing rear crisis state at ${targetUrl}`);
|
||||||
} finally {
|
} finally {
|
||||||
await browser?.close();
|
await browser?.close();
|
||||||
if (serverProcess && !serverProcess.killed) {
|
if (serverProcess && !serverProcess.killed) {
|
||||||
|
|||||||
108
src/assets/images/battle/forty-second-battle-map.svg
Normal file
108
src/assets/images/battle/forty-second-battle-map.svg
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8400 6600" width="8400" height="6600">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="plain" x1="0" y1="0" x2="1" y2="1">
|
||||||
|
<stop offset="0" stop-color="#6f7148"/>
|
||||||
|
<stop offset="0.5" stop-color="#baa365"/>
|
||||||
|
<stop offset="1" stop-color="#4d5235"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="water" x1="0" y1="0" x2="1" y2="0">
|
||||||
|
<stop offset="0" stop-color="#122b4a"/>
|
||||||
|
<stop offset="0.5" stop-color="#6baac0"/>
|
||||||
|
<stop offset="1" stop-color="#0d2439"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="road" x1="0" y1="0" x2="1" y2="1">
|
||||||
|
<stop offset="0" stop-color="#5a4227"/>
|
||||||
|
<stop offset="0.52" stop-color="#c5a669"/>
|
||||||
|
<stop offset="1" stop-color="#6a4b2f"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="warehouse" x1="0" y1="0" x2="0" y2="1">
|
||||||
|
<stop offset="0" stop-color="#a68452"/>
|
||||||
|
<stop offset="1" stop-color="#5c4630"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="ridge" x1="0" y1="0" x2="0" y2="1">
|
||||||
|
<stop offset="0" stop-color="#686845"/>
|
||||||
|
<stop offset="0.55" stop-color="#9a8e56"/>
|
||||||
|
<stop offset="1" stop-color="#3a3c26"/>
|
||||||
|
</linearGradient>
|
||||||
|
<pattern id="grain" width="120" height="120" patternUnits="userSpaceOnUse">
|
||||||
|
<path d="M14 28h28M58 20h24M96 36h16M24 76h36M80 88h26M18 110h24M66 108h24" stroke="#312e1f" stroke-width="8" stroke-linecap="round" opacity="0.18"/>
|
||||||
|
<circle cx="102" cy="92" r="8" fill="#dbc16f" opacity="0.18"/>
|
||||||
|
<circle cx="34" cy="42" r="6" fill="#5c5636" opacity="0.2"/>
|
||||||
|
</pattern>
|
||||||
|
<pattern id="forest" width="180" height="160" patternUnits="userSpaceOnUse">
|
||||||
|
<circle cx="34" cy="54" r="35" fill="#233818"/>
|
||||||
|
<circle cx="76" cy="38" r="32" fill="#516b30"/>
|
||||||
|
<circle cx="116" cy="72" r="39" fill="#1c3016"/>
|
||||||
|
<circle cx="144" cy="48" r="26" fill="#6d8440"/>
|
||||||
|
<path d="M34 88c34 18 76 16 110-4" stroke="#121b10" stroke-width="10" opacity="0.36"/>
|
||||||
|
</pattern>
|
||||||
|
<pattern id="stone" width="140" height="120" patternUnits="userSpaceOnUse">
|
||||||
|
<rect width="140" height="120" fill="#6d6559"/>
|
||||||
|
<path d="M0 40h140M0 82h140M30 0v40M94 40v42M48 82v38M118 82v38" stroke="#2c2821" stroke-width="8" opacity="0.46"/>
|
||||||
|
<path d="M12 20h28M76 62h34M20 102h24" stroke="#b6a274" stroke-width="8" opacity="0.34"/>
|
||||||
|
</pattern>
|
||||||
|
<filter id="shadow" x="-10%" y="-10%" width="120%" height="120%">
|
||||||
|
<feDropShadow dx="0" dy="14" stdDeviation="18" flood-color="#17130b" flood-opacity="0.42"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<rect width="8400" height="6600" fill="url(#plain)"/>
|
||||||
|
<rect width="8400" height="6600" fill="url(#grain)" opacity="0.82"/>
|
||||||
|
|
||||||
|
<path d="M1920 -120 C1600 840 2180 1800 1880 2780 C1660 3600 2140 4580 1900 5900" fill="none" stroke="#0f2948" stroke-width="520" stroke-linecap="round"/>
|
||||||
|
<path d="M1920 -120 C1600 840 2180 1800 1880 2780 C1660 3600 2140 4580 1900 5900" fill="none" stroke="url(#water)" stroke-width="392" stroke-linecap="round"/>
|
||||||
|
<path d="M3760 920 C3500 2120 3960 3180 3700 4180 C3500 5000 3880 5760 3740 6680" fill="none" stroke="#0f2948" stroke-width="410" stroke-linecap="round"/>
|
||||||
|
<path d="M3760 920 C3500 2120 3960 3180 3700 4180 C3500 5000 3880 5760 3740 6680" fill="none" stroke="url(#water)" stroke-width="300" stroke-linecap="round"/>
|
||||||
|
<path d="M5600 360 C5360 1260 5740 2360 5540 3560 C5360 4480 5760 5000 5580 5480" fill="none" stroke="#0f2948" stroke-width="360" stroke-linecap="round"/>
|
||||||
|
<path d="M5600 360 C5360 1260 5740 2360 5540 3560 C5360 4480 5760 5000 5580 5480" fill="none" stroke="url(#water)" stroke-width="260" stroke-linecap="round"/>
|
||||||
|
<path d="M2240 3620 C3660 3420 5100 3580 7240 3680" fill="none" stroke="#0f2948" stroke-width="330" stroke-linecap="round"/>
|
||||||
|
<path d="M2240 3620 C3660 3420 5100 3580 7240 3680" fill="none" stroke="url(#water)" stroke-width="238" stroke-linecap="round"/>
|
||||||
|
<path d="M7200 1900 C6940 2680 7360 3600 7180 4740" fill="none" stroke="#0f2948" stroke-width="290" stroke-linecap="round"/>
|
||||||
|
<path d="M7200 1900 C6940 2680 7360 3600 7180 4740" fill="none" stroke="url(#water)" stroke-width="198" stroke-linecap="round"/>
|
||||||
|
|
||||||
|
<path d="M-160 0 L1760 0 L1640 3100 L720 2820 L120 1820 Z" fill="url(#ridge)" filter="url(#shadow)" opacity="0.82"/>
|
||||||
|
<path d="M2920 120 L7040 20 L6740 2300 L4840 2060 L3800 1360 L2780 1760 Z" fill="url(#ridge)" filter="url(#shadow)" opacity="0.76"/>
|
||||||
|
<path d="M7240 -80 L8460 -80 L8420 1500 L7240 1420 Z" fill="url(#ridge)" filter="url(#shadow)" opacity="0.86"/>
|
||||||
|
<path d="M3300 5900 L5600 5740 L5680 6660 L3120 6660 Z" fill="url(#ridge)" filter="url(#shadow)" opacity="0.78"/>
|
||||||
|
|
||||||
|
<path d="M320 1280 C1160 920 2140 1160 3180 1340 L3120 4860 C1900 4860 920 4480 260 4880 Z" fill="url(#forest)" opacity="0.86"/>
|
||||||
|
<path d="M3080 2160 C3740 1840 4480 2080 4960 2780 L4880 5360 C3980 5380 3220 4860 2940 4180 Z" fill="url(#forest)" opacity="0.82"/>
|
||||||
|
<path d="M5320 5020 C6200 4700 7180 4840 8400 4540 L8400 6400 C7000 6440 5900 6540 5220 6300 Z" fill="url(#forest)" opacity="0.88"/>
|
||||||
|
|
||||||
|
<path d="M720 6160 C1780 5900 3120 5840 4560 5360 C5740 4960 6720 4440 7600 3760 C7940 3480 8120 3060 8480 2540" fill="none" stroke="#523d24" stroke-width="330" stroke-linecap="round" stroke-linejoin="round" opacity="0.94"/>
|
||||||
|
<path d="M720 6160 C1780 5900 3120 5840 4560 5360 C5740 4960 6720 4440 7600 3760 C7940 3480 8120 3060 8480 2540" fill="none" stroke="url(#road)" stroke-width="198" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M2260 3000 C3800 2820 5360 2980 7600 3140" fill="none" stroke="#523d24" stroke-width="250" stroke-linecap="round" opacity="0.9"/>
|
||||||
|
<path d="M2260 3000 C3800 2820 5360 2980 7600 3140" fill="none" stroke="url(#road)" stroke-width="140" stroke-linecap="round"/>
|
||||||
|
|
||||||
|
<rect x="5740" y="4040" width="1220" height="980" rx="30" fill="url(#stone)" filter="url(#shadow)"/>
|
||||||
|
<rect x="6440" y="2840" width="1360" height="1080" rx="28" fill="url(#stone)" filter="url(#shadow)" opacity="0.88"/>
|
||||||
|
<rect x="7320" y="1420" width="980" height="1440" rx="26" fill="url(#stone)" filter="url(#shadow)" opacity="0.9"/>
|
||||||
|
<path d="M5740 5160 h980 v300 h-980zM6040 4040 v1420M6440 2840 v1120M7320 1420 v1500" stroke="#2c2720" stroke-width="34" fill="none" opacity="0.46"/>
|
||||||
|
|
||||||
|
<g filter="url(#shadow)">
|
||||||
|
<rect x="2120" y="5660" width="520" height="400" fill="#91703e" stroke="#2c2219" stroke-width="28"/>
|
||||||
|
<path d="M2080 5660 L2380 5320 L2680 5660 Z" fill="#c08a35" stroke="#2c2219" stroke-width="28"/>
|
||||||
|
<rect x="4420" y="5020" width="620" height="440" fill="url(#warehouse)" stroke="#2c2219" stroke-width="26"/>
|
||||||
|
<path d="M4380 5020 L4730 4680 L5080 5020 Z" fill="#b78232" stroke="#2c2219" stroke-width="26"/>
|
||||||
|
<rect x="5860" y="4340" width="560" height="420" fill="url(#warehouse)" stroke="#2c2219" stroke-width="24"/>
|
||||||
|
<path d="M5820 4340 L6140 4040 L6460 4340 Z" fill="#c18c36" stroke="#2c2219" stroke-width="24"/>
|
||||||
|
<rect x="7220" y="3600" width="510" height="390" fill="#8d6b36" stroke="#2c2219" stroke-width="24"/>
|
||||||
|
<path d="M7180 3600 L7475 3300 L7770 3600 Z" fill="#ba8432" stroke="#2c2219" stroke-width="24"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g opacity="0.9" filter="url(#shadow)">
|
||||||
|
<path d="M2840 5520 h520 l180 170 -180 170 h-520 l-180-170z" fill="#5f6b6d" stroke="#1f2528" stroke-width="26"/>
|
||||||
|
<path d="M3380 5550 l360-160 80 60 -300 240z" fill="#c6d2d6" stroke="#1f2528" stroke-width="18"/>
|
||||||
|
<path d="M5100 4740 h460 l160 150 -160 150 h-460 l-160-150z" fill="#526266" stroke="#1f2528" stroke-width="24"/>
|
||||||
|
<path d="M5570 4770 l310-140 72 54 -260 210z" fill="#c6d2d6" stroke="#1f2528" stroke-width="16"/>
|
||||||
|
<path d="M6900 3160 h430 l150 140 -150 140 h-430 l-150-140z" fill="#56676a" stroke="#1f2528" stroke-width="24"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g opacity="0.34" stroke="#182e42" stroke-width="18" stroke-linecap="round">
|
||||||
|
<path d="M2340 3820 c960 150 2100 100 3700 280"/>
|
||||||
|
<path d="M2020 1460 c540 220 1040 180 1580 30"/>
|
||||||
|
<path d="M5580 1320 c340 220 700 220 1100 80"/>
|
||||||
|
<path d="M6120 5680 c600-160 1220-100 1800 140"/>
|
||||||
|
<path d="M7060 2480 c280 120 600 120 920 20"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 7.9 KiB |
@@ -28,6 +28,10 @@ import {
|
|||||||
fortyFirstBattleMap,
|
fortyFirstBattleMap,
|
||||||
fortyFirstBattleUnits,
|
fortyFirstBattleUnits,
|
||||||
fortyFirstBattleVictoryPages,
|
fortyFirstBattleVictoryPages,
|
||||||
|
fortySecondBattleBonds,
|
||||||
|
fortySecondBattleMap,
|
||||||
|
fortySecondBattleUnits,
|
||||||
|
fortySecondBattleVictoryPages,
|
||||||
firstBattleMap,
|
firstBattleMap,
|
||||||
firstBattleUnits,
|
firstBattleUnits,
|
||||||
firstBattleVictoryPages,
|
firstBattleVictoryPages,
|
||||||
@@ -210,7 +214,8 @@ export type BattleScenarioId =
|
|||||||
| 'thirty-eighth-battle-jing-defense'
|
| 'thirty-eighth-battle-jing-defense'
|
||||||
| 'thirty-ninth-battle-fan-castle-vanguard'
|
| 'thirty-ninth-battle-fan-castle-vanguard'
|
||||||
| 'fortieth-battle-han-river-flood'
|
| 'fortieth-battle-han-river-flood'
|
||||||
| 'forty-first-battle-fan-castle-siege';
|
| 'forty-first-battle-fan-castle-siege'
|
||||||
|
| 'forty-second-battle-jing-rear-crisis';
|
||||||
|
|
||||||
export type BattleObjectiveKind = 'defeat-leader' | 'keep-unit-alive' | 'secure-terrain' | 'quick-victory';
|
export type BattleObjectiveKind = 'defeat-leader' | 'keep-unit-alive' | 'secure-terrain' | 'quick-victory';
|
||||||
|
|
||||||
@@ -2653,6 +2658,69 @@ export const fortyFirstBattleScenario: BattleScenarioDefinition = {
|
|||||||
nextCampScene: 'CampScene'
|
nextCampScene: 'CampScene'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const fortySecondBattleScenario: BattleScenarioDefinition = {
|
||||||
|
id: 'forty-second-battle-jing-rear-crisis',
|
||||||
|
title: '강릉 나루 경계전',
|
||||||
|
victoryConditionLabel: '여몽 정찰대 격퇴',
|
||||||
|
defeatConditionLabel: '유비 또는 관우 퇴각',
|
||||||
|
openingObjectiveLines: [
|
||||||
|
'번성의 성문은 흔들렸지만 강릉 나루에는 강동의 작은 배가 늘었습니다. 상선으로 위장한 정찰대를 몰아내 후방의 창고를 지키십시오.',
|
||||||
|
'관우가 번성 전선과 형주 후방을 함께 붙잡아야 합니다. 관우가 쓰러지면 전선의 승세와 후방의 민심이 동시에 흔들립니다.',
|
||||||
|
'여몽은 정찰대를 깊숙이 보내고, 육손은 부드러운 말로 빈틈을 살핍니다. 마량과 미축 같은 후방 담당을 데려가면 균열을 읽고 창고를 지키기 쉽습니다.'
|
||||||
|
],
|
||||||
|
map: fortySecondBattleMap,
|
||||||
|
units: fortySecondBattleUnits,
|
||||||
|
bonds: fortySecondBattleBonds,
|
||||||
|
mapTextureKey: 'battle-map-forty-second',
|
||||||
|
leaderUnitId: 'jing-rear-leader-lu-meng',
|
||||||
|
quickVictoryTurnLimit: 68,
|
||||||
|
baseVictoryGold: 8520,
|
||||||
|
objectives: [
|
||||||
|
{
|
||||||
|
id: 'leader',
|
||||||
|
kind: 'defeat-leader',
|
||||||
|
label: '여몽 정찰대 격퇴',
|
||||||
|
rewardGold: 5560,
|
||||||
|
unitId: 'jing-rear-leader-lu-meng'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'liu-bei',
|
||||||
|
kind: 'keep-unit-alive',
|
||||||
|
label: '유비 생존',
|
||||||
|
rewardGold: 1320,
|
||||||
|
unitId: 'liu-bei'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'guan-yu',
|
||||||
|
kind: 'keep-unit-alive',
|
||||||
|
label: '관우 생존',
|
||||||
|
rewardGold: 2080,
|
||||||
|
unitId: 'guan-yu'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'warehouse',
|
||||||
|
kind: 'secure-terrain',
|
||||||
|
label: '강릉 창고 확보',
|
||||||
|
rewardGold: 2680,
|
||||||
|
terrain: 'village'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'quick',
|
||||||
|
kind: 'quick-victory',
|
||||||
|
label: '68턴 이내 승리',
|
||||||
|
rewardGold: 1960,
|
||||||
|
maxTurn: 68
|
||||||
|
}
|
||||||
|
],
|
||||||
|
defeatConditions: [
|
||||||
|
{ kind: 'unit-defeated', unitId: 'liu-bei' },
|
||||||
|
{ kind: 'unit-defeated', unitId: 'guan-yu' }
|
||||||
|
],
|
||||||
|
itemRewards: ['콩 40', '상처약 30', '탁주 12', '강동 정찰 기록 1', '강릉 창고 장부 1'],
|
||||||
|
victoryPages: fortySecondBattleVictoryPages,
|
||||||
|
nextCampScene: 'CampScene'
|
||||||
|
};
|
||||||
|
|
||||||
export const defaultBattleScenarioId: BattleScenarioId = firstBattleScenario.id;
|
export const defaultBattleScenarioId: BattleScenarioId = firstBattleScenario.id;
|
||||||
|
|
||||||
export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition> = {
|
export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition> = {
|
||||||
@@ -2696,7 +2764,8 @@ export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition>
|
|||||||
'thirty-eighth-battle-jing-defense': thirtyEighthBattleScenario,
|
'thirty-eighth-battle-jing-defense': thirtyEighthBattleScenario,
|
||||||
'thirty-ninth-battle-fan-castle-vanguard': thirtyNinthBattleScenario,
|
'thirty-ninth-battle-fan-castle-vanguard': thirtyNinthBattleScenario,
|
||||||
'fortieth-battle-han-river-flood': fortiethBattleScenario,
|
'fortieth-battle-han-river-flood': fortiethBattleScenario,
|
||||||
'forty-first-battle-fan-castle-siege': fortyFirstBattleScenario
|
'forty-first-battle-fan-castle-siege': fortyFirstBattleScenario,
|
||||||
|
'forty-second-battle-jing-rear-crisis': fortySecondBattleScenario
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultBattleScenario = battleScenarios[defaultBattleScenarioId];
|
export const defaultBattleScenario = battleScenarios[defaultBattleScenarioId];
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
eleventhBattleScenario,
|
eleventhBattleScenario,
|
||||||
fortiethBattleScenario,
|
fortiethBattleScenario,
|
||||||
fortyFirstBattleScenario,
|
fortyFirstBattleScenario,
|
||||||
|
fortySecondBattleScenario,
|
||||||
fifthBattleScenario,
|
fifthBattleScenario,
|
||||||
fifteenthBattleScenario,
|
fifteenthBattleScenario,
|
||||||
fourteenthBattleScenario,
|
fourteenthBattleScenario,
|
||||||
@@ -54,6 +55,8 @@ import {
|
|||||||
fortiethBattleVictoryPages,
|
fortiethBattleVictoryPages,
|
||||||
fortyFirstBattleIntroPages,
|
fortyFirstBattleIntroPages,
|
||||||
fortyFirstBattleVictoryPages,
|
fortyFirstBattleVictoryPages,
|
||||||
|
fortySecondBattleIntroPages,
|
||||||
|
fortySecondBattleVictoryPages,
|
||||||
fifthBattleIntroPages,
|
fifthBattleIntroPages,
|
||||||
fifthBattleVictoryPages,
|
fifthBattleVictoryPages,
|
||||||
fifteenthBattleIntroPages,
|
fifteenthBattleIntroPages,
|
||||||
@@ -594,13 +597,24 @@ const sortieFlows: Record<string, SortieFlow> = {
|
|||||||
},
|
},
|
||||||
[fortyFirstBattleScenario.id]: {
|
[fortyFirstBattleScenario.id]: {
|
||||||
afterBattleId: fortyFirstBattleScenario.id,
|
afterBattleId: fortyFirstBattleScenario.id,
|
||||||
eyebrow: '다음 장 준비',
|
eyebrow: '다음 전장',
|
||||||
title: '형주 후방 경계',
|
title: fortySecondBattleScenario.title,
|
||||||
description:
|
description:
|
||||||
'번성의 외성 방어선은 흔들렸지만 강동의 그림자가 더 가까워졌습니다. 다음 장에서는 번성 승세와 형주 후방의 균열을 함께 다루며 관우 전선의 위기를 키웁니다.',
|
'번성의 외성 방어선은 흔들렸지만 강동의 그림자가 더 가까워졌습니다. 다음 출진에서는 강릉 동쪽 나루와 창고를 노리는 정찰대를 몰아내며 형주 후방의 첫 균열을 확인합니다.',
|
||||||
rewardHint: '다음 장: 형주 후방 위기와 오군 침투 준비 중',
|
rewardHint: `예상 보상: ${fortySecondBattleScenario.title} 개방 / 강릉 창고 장부`,
|
||||||
pages: fortyFirstBattleVictoryPages,
|
nextBattleId: fortySecondBattleScenario.id,
|
||||||
unavailableNotice: '형주 후방 위기와 오군 침투는 다음 작업에서 이어집니다. 지금은 군영에서 공성전 성장, 공명도, 보급을 정비할 수 있습니다.'
|
campaignStep: 'forty-second-battle',
|
||||||
|
pages: [...fortyFirstBattleVictoryPages, ...fortySecondBattleIntroPages]
|
||||||
|
},
|
||||||
|
[fortySecondBattleScenario.id]: {
|
||||||
|
afterBattleId: fortySecondBattleScenario.id,
|
||||||
|
eyebrow: '다음 장 준비',
|
||||||
|
title: '형주 균열 심화',
|
||||||
|
description:
|
||||||
|
'강릉 나루는 지켰지만 강동의 침투는 이미 더 넓은 후방을 살피고 있습니다. 다음 장에서는 강릉과 공안의 흔들림, 장수들의 불신, 오군의 본격적인 움직임을 다룹니다.',
|
||||||
|
rewardHint: '다음 장: 형주 후방 붕괴와 오군 침투 준비 중',
|
||||||
|
pages: fortySecondBattleVictoryPages,
|
||||||
|
unavailableNotice: '형주 후방 붕괴와 오군 침투는 다음 작업에서 이어집니다. 지금은 군영에서 나루 경계의 성장, 공명도, 보급을 정비할 수 있습니다.'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2717,6 +2717,69 @@ export const fortyFirstBattleVictoryPages: StoryPage[] = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const fortySecondBattleIntroPages: StoryPage[] = [
|
||||||
|
{
|
||||||
|
id: 'forty-second-river-rumors',
|
||||||
|
bgm: 'story-dark',
|
||||||
|
chapter: '강릉의 불안',
|
||||||
|
background: 'story-militia',
|
||||||
|
speaker: '마량',
|
||||||
|
text: '번성 성문은 흔들리고 있지만, 강릉 동쪽 나루에는 낯선 상선이 늘었습니다. 장사꾼의 말투 속에 군령이 섞여 있고, 밤 신호는 평소보다 늦게 올라옵니다.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'forty-second-lu-meng-shadow',
|
||||||
|
bgm: 'battle-prep',
|
||||||
|
chapter: '흰 옷의 그림자',
|
||||||
|
background: 'story-liu-bei',
|
||||||
|
speaker: '제갈량',
|
||||||
|
text: '강동의 장수들은 칼을 들고 오지 않을 수도 있습니다. 흰 옷의 상인, 약재 배, 빈 곡식 자루가 모두 길을 재는 눈이 될 수 있습니다.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'forty-second-guan-yu-rear-order',
|
||||||
|
bgm: 'battle-prep',
|
||||||
|
chapter: '후방 경계령',
|
||||||
|
background: 'story-three-heroes',
|
||||||
|
speaker: '관우',
|
||||||
|
portrait: 'guanYu',
|
||||||
|
text: '번성을 치는 손을 늦출 수는 없으나, 형주의 뒤를 비울 수도 없소. 나루와 창고를 지키며 강동 정찰대를 몰아내시오.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'forty-second-sortie',
|
||||||
|
bgm: 'battle-prep',
|
||||||
|
chapter: '강릉 나루 경계전',
|
||||||
|
background: 'story-sortie',
|
||||||
|
speaker: '유비',
|
||||||
|
portrait: 'liuBei',
|
||||||
|
text: '전선의 승리와 후방의 평온은 따로 있지 않다. 관우의 깃발이 번성 앞에 선 동안, 강릉 나루의 작은 흔들림까지 놓치지 말라.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const fortySecondBattleVictoryPages: StoryPage[] = [
|
||||||
|
{
|
||||||
|
id: 'forty-second-victory-river-watch',
|
||||||
|
bgm: 'militia-theme',
|
||||||
|
chapter: '나루의 밤이 밝아지다',
|
||||||
|
background: 'story-sortie',
|
||||||
|
text: '강릉 동쪽 나루의 정찰선은 물러났고, 강변 창고의 불안은 잠시 가라앉았습니다. 그러나 붙잡힌 척후의 말은 오히려 더 큰 위기를 가리켰습니다.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'forty-second-lu-xun-letter',
|
||||||
|
bgm: 'story-dark',
|
||||||
|
chapter: '부드러운 글과 날카로운 뜻',
|
||||||
|
background: 'story-three-heroes',
|
||||||
|
speaker: '마량',
|
||||||
|
text: '강동에서 온 문서는 예를 갖추고 있었지만, 글 사이에는 형주의 빈틈을 재는 뜻이 숨어 있었습니다. 승리보다 후방의 믿음이 더 급해졌습니다.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'forty-second-next-crack',
|
||||||
|
bgm: 'story-dark',
|
||||||
|
chapter: '갈라지는 형주',
|
||||||
|
background: 'story-militia',
|
||||||
|
speaker: '제갈량',
|
||||||
|
text: '나루 하나는 지켰으나, 강릉과 공안의 장수들이 흔들리기 시작했습니다. 다음 장에서는 형주 후방의 균열이 더 노골적인 배신과 침투로 이어질 것입니다.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
export const firstBattleMap: BattleMap = {
|
export const firstBattleMap: BattleMap = {
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 18,
|
height: 18,
|
||||||
@@ -3108,6 +3171,12 @@ export const fortyFirstBattleMap: BattleMap = {
|
|||||||
terrain: createFortyFirstBattleTerrain()
|
terrain: createFortyFirstBattleTerrain()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const fortySecondBattleMap: BattleMap = {
|
||||||
|
width: 84,
|
||||||
|
height: 66,
|
||||||
|
terrain: createFortySecondBattleTerrain()
|
||||||
|
};
|
||||||
|
|
||||||
export const firstBattleUnits: UnitData[] = [
|
export const firstBattleUnits: UnitData[] = [
|
||||||
{
|
{
|
||||||
id: 'liu-bei',
|
id: 'liu-bei',
|
||||||
@@ -14648,6 +14717,89 @@ export const fortyFirstBattleUnits: UnitData[] = [
|
|||||||
createThirtyFirstEnemyUnit('fan-siege-leader-cao-ren', '조인', '번성 수비장', 'rebelLeader', 99, 676, 172, 78, 18)
|
createThirtyFirstEnemyUnit('fan-siege-leader-cao-ren', '조인', '번성 수비장', 'rebelLeader', 99, 676, 172, 78, 18)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const fortySecondBattleAllyPositions: Record<string, { x: number; y: number }> = {
|
||||||
|
'liu-bei': { x: 6, y: 59 },
|
||||||
|
'guan-yu': { x: 13, y: 54 },
|
||||||
|
'zhang-fei': { x: 7, y: 61 },
|
||||||
|
'jian-yong': { x: 5, y: 62 },
|
||||||
|
'mi-zhu': { x: 9, y: 60 },
|
||||||
|
'sun-qian': { x: 10, y: 63 },
|
||||||
|
'zhao-yun': { x: 16, y: 57 },
|
||||||
|
'zhuge-liang': { x: 10, y: 56 },
|
||||||
|
'ma-liang': { x: 15, y: 59 },
|
||||||
|
'yi-ji': { x: 17, y: 62 },
|
||||||
|
'gong-zhi': { x: 18, y: 60 },
|
||||||
|
'huang-zhong': { x: 19, y: 55 },
|
||||||
|
'wei-yan': { x: 17, y: 53 },
|
||||||
|
'pang-tong': { x: 14, y: 57 },
|
||||||
|
'fa-zheng': { x: 20, y: 59 },
|
||||||
|
'wu-yi': { x: 21, y: 56 },
|
||||||
|
'yan-yan': { x: 22, y: 58 },
|
||||||
|
'li-yan': { x: 20, y: 53 },
|
||||||
|
'huang-quan': { x: 23, y: 60 },
|
||||||
|
'ma-chao': { x: 24, y: 54 },
|
||||||
|
'ma-dai': { x: 25, y: 56 },
|
||||||
|
'wang-ping': { x: 23, y: 52 }
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fortySecondBattleUnits: UnitData[] = [
|
||||||
|
...[
|
||||||
|
...firstBattleUnits.filter((unit) => unit.faction === 'ally'),
|
||||||
|
...xuzhouRecruitUnits,
|
||||||
|
...caoBreakRecruitUnits,
|
||||||
|
...liuBiaoRecruitUnits,
|
||||||
|
...zhugeRecruitUnits,
|
||||||
|
...jingzhouRecruitUnits,
|
||||||
|
...guiyangRecruitUnits,
|
||||||
|
...wulingRecruitUnits,
|
||||||
|
...changshaRecruitUnits,
|
||||||
|
...yizhouRecruitUnits,
|
||||||
|
...fuPassRecruitUnits,
|
||||||
|
...luoCastleRecruitUnits,
|
||||||
|
...luoCastleProperRecruitUnits,
|
||||||
|
...chengduPressureRecruitUnits,
|
||||||
|
...chengduSurrenderRecruitUnits,
|
||||||
|
...hanzhongOpeningRecruitUnits,
|
||||||
|
...hanzhongScoutRecruitUnits,
|
||||||
|
...hanzhongMainRecruitUnits
|
||||||
|
].map((unit) => placeScenarioUnit(unit, fortySecondBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-scout-a', '강동 척후', '흰 옷 척후', 'bandit', 94, 382, 126, 30, 57),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-scout-b', '강동 척후', '상선 척후', 'bandit', 94, 382, 126, 39, 54),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-scout-c', '강동 척후', '약재선 척후', 'bandit', 95, 390, 128, 51, 49),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-scout-d', '강동 척후', '북나루 척후', 'bandit', 95, 390, 128, 64, 43),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-scout-e', '강동 척후', '동림 척후', 'bandit', 96, 398, 130, 75, 36),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-infantry-a', '강동 보병', '나루 보병', 'yellowTurban', 95, 558, 152, 43, 50),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-infantry-b', '강동 보병', '창고 보병', 'yellowTurban', 95, 558, 152, 54, 45),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-infantry-c', '강동 보병', '강릉 보병', 'yellowTurban', 96, 570, 154, 63, 38),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-infantry-d', '강동 보병', '동문 보병', 'yellowTurban', 96, 570, 154, 72, 31),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-infantry-e', '강동 보병', '후방 보병', 'yellowTurban', 97, 582, 156, 78, 24),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-infantry-f', '강동 보병', '공안 보병', 'yellowTurban', 97, 582, 156, 80, 15),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-archer-a', '강동 궁병', '강안 궁병', 'archer', 95, 406, 132, 35, 58),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-archer-b', '강동 궁병', '상선 궁병', 'archer', 96, 414, 134, 49, 51),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-archer-c', '강동 궁병', '창고 궁병', 'archer', 96, 414, 134, 59, 44),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-archer-d', '강동 궁병', '동림 궁병', 'archer', 97, 422, 136, 70, 36),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-archer-e', '강동 궁병', '공안 궁병', 'archer', 97, 422, 136, 79, 20),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-cavalry-a', '강동 기병', '나루 기병', 'cavalry', 96, 576, 156, 37, 60),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-cavalry-b', '강동 기병', '창고 기병', 'cavalry', 96, 576, 156, 52, 53),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-cavalry-c', '강동 기병', '동림 기병', 'cavalry', 97, 588, 158, 67, 42),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-cavalry-d', '강동 기병', '공안 기병', 'cavalry', 97, 588, 158, 77, 32),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-guard-a', '강동 수비대', '상선 수비대', 'yellowTurban', 98, 626, 164, 58, 42),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-guard-b', '강동 수비대', '창고 수비대', 'yellowTurban', 98, 626, 164, 68, 34),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-guard-c', '강동 수비대', '여몽 수비대', 'yellowTurban', 99, 638, 166, 75, 27),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-guard-d', '강동 수비대', '동문 수비대', 'yellowTurban', 99, 638, 166, 81, 18),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-strategist-a', '강동 책사', '상선 책사', 'strategist', 96, 422, 136, 45, 55),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-strategist-b', '강동 책사', '강릉 책사', 'strategist', 97, 430, 138, 62, 39),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-strategist-c', '강동 책사', '공안 책사', 'strategist', 98, 438, 140, 77, 22),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-ambusher-a', '강동 복병', '흰 옷 복병', 'bandit', 95, 392, 130, 32, 62),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-ambusher-b', '강동 복병', '창고 복병', 'bandit', 96, 400, 132, 55, 57),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-ambusher-c', '강동 복병', '동림 복병', 'bandit', 96, 400, 132, 72, 45),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-marine-a', '강동 수군', '나루 수군', 'yellowTurban', 96, 570, 154, 41, 61),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-marine-b', '강동 수군', '상선 수군', 'yellowTurban', 97, 582, 156, 48, 58),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-officer-lu-xun', '육손', '강동 설객', 'strategist', 99, 462, 146, 71, 29),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-officer-mi-fang', '미방', '흔들리는 후방장', 'rebelLeader', 98, 620, 162, 66, 48),
|
||||||
|
createThirtyFirstEnemyUnit('jing-rear-leader-lu-meng', '여몽', '강동 도독', 'rebelLeader', 100, 690, 176, 80, 26)
|
||||||
|
];
|
||||||
|
|
||||||
export const firstBattleBonds: BattleBond[] = [
|
export const firstBattleBonds: BattleBond[] = [
|
||||||
{
|
{
|
||||||
id: 'liu-bei__guan-yu',
|
id: 'liu-bei__guan-yu',
|
||||||
@@ -15253,6 +15405,33 @@ export const fanCastleSiegeBonds: BattleBond[] = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const jingRearCrisisBonds: BattleBond[] = [
|
||||||
|
{
|
||||||
|
id: 'guan-yu__mi-zhu_rear',
|
||||||
|
unitIds: ['guan-yu', 'mi-zhu'],
|
||||||
|
title: '후방 창고의 신뢰',
|
||||||
|
level: 27,
|
||||||
|
exp: 0,
|
||||||
|
description: '관우의 엄정한 군령과 미축의 보급 감각이 이어지면, 강릉 창고와 나루를 노리는 침투에 더 빠르게 대응합니다.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'guan-yu__ma-liang_rear',
|
||||||
|
unitIds: ['guan-yu', 'ma-liang'],
|
||||||
|
title: '형주 후방 경계',
|
||||||
|
level: 28,
|
||||||
|
exp: 0,
|
||||||
|
description: '관우의 전선 압박과 마량의 형주 민심 판단이 맞물리면, 강동의 부드러운 말과 숨은 정찰을 더 빨리 읽어 냅니다.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'liu-bei__mi-zhu_rear',
|
||||||
|
unitIds: ['liu-bei', 'mi-zhu'],
|
||||||
|
title: '백성과 창고',
|
||||||
|
level: 25,
|
||||||
|
exp: 0,
|
||||||
|
description: '유비의 민심과 미축의 보급선이 이어지면, 전투 사이 상인·백성 이벤트에서 후방 안정 보너스가 커집니다.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
export const secondBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
export const secondBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
||||||
export const thirdBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
export const thirdBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
||||||
export const fourthBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
export const fourthBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
||||||
@@ -15321,6 +15500,9 @@ export const fortiethBattleBonds: BattleBond[] = [...thirtyNinthBattleBonds, ...
|
|||||||
export const fortyFirstBattleBonds: BattleBond[] = [...fortiethBattleBonds, ...fanCastleSiegeBonds].map(
|
export const fortyFirstBattleBonds: BattleBond[] = [...fortiethBattleBonds, ...fanCastleSiegeBonds].map(
|
||||||
cloneBattleBondForScenario
|
cloneBattleBondForScenario
|
||||||
);
|
);
|
||||||
|
export const fortySecondBattleBonds: BattleBond[] = [...fortyFirstBattleBonds, ...jingRearCrisisBonds].map(
|
||||||
|
cloneBattleBondForScenario
|
||||||
|
);
|
||||||
|
|
||||||
function createEighthBattleTerrain(): TerrainType[][] {
|
function createEighthBattleTerrain(): TerrainType[][] {
|
||||||
return Array.from({ length: 22 }, (_, y) =>
|
return Array.from({ length: 22 }, (_, y) =>
|
||||||
@@ -17292,6 +17474,81 @@ function createFortyFirstBattleTerrain(): TerrainType[][] {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createFortySecondBattleTerrain(): TerrainType[][] {
|
||||||
|
return Array.from({ length: 66 }, (_, y) =>
|
||||||
|
Array.from({ length: 84 }, (_, x): TerrainType => {
|
||||||
|
if (x <= 7 && y >= 58) {
|
||||||
|
return 'camp';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(x >= 57 && x <= 68 && y >= 39 && y <= 51) ||
|
||||||
|
(x >= 64 && x <= 76 && y >= 27 && y <= 39) ||
|
||||||
|
(x >= 72 && x <= 83 && y >= 14 && y <= 29) ||
|
||||||
|
(x >= 76 && x <= 83 && y >= 6 && y <= 16)
|
||||||
|
) {
|
||||||
|
return 'fort';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(x >= 21 && x <= 26 && y >= 55 && y <= 60) ||
|
||||||
|
(x >= 43 && x <= 49 && y >= 49 && y <= 53) ||
|
||||||
|
(x >= 58 && x <= 64 && y >= 43 && y <= 47) ||
|
||||||
|
(x >= 72 && x <= 78 && y >= 35 && y <= 40)
|
||||||
|
) {
|
||||||
|
return 'village';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(x >= 16 && x <= 22 && y >= 0 && y <= 57) ||
|
||||||
|
(x >= 35 && x <= 39 && y >= 9 && y <= 64) ||
|
||||||
|
(x >= 54 && x <= 58 && y >= 4 && y <= 53) ||
|
||||||
|
(x >= 70 && x <= 73 && y >= 18 && y <= 46) ||
|
||||||
|
(y >= 34 && y <= 38 && x >= 22 && x <= 72) ||
|
||||||
|
(y >= 51 && y <= 54 && x >= 36 && x <= 66)
|
||||||
|
) {
|
||||||
|
return 'river';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(y >= 60 && x >= 7 && x <= 32) ||
|
||||||
|
(x >= 31 && x <= 47 && y >= 55 && y <= 60) ||
|
||||||
|
(x >= 46 && x <= 62 && y >= 49 && y <= 55) ||
|
||||||
|
(x >= 61 && x <= 73 && y >= 42 && y <= 49) ||
|
||||||
|
(x >= 72 && x <= 82 && y >= 33 && y <= 42) ||
|
||||||
|
(x >= 75 && x <= 83 && y >= 20 && y <= 33) ||
|
||||||
|
(x >= 58 && x <= 81 && y >= 17 && y <= 21) ||
|
||||||
|
(y >= 28 && y <= 31 && x >= 22 && x <= 75)
|
||||||
|
) {
|
||||||
|
return 'road';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(x >= 4 && x <= 30 && y >= 13 && y <= 47) ||
|
||||||
|
(x >= 30 && x <= 49 && y >= 20 && y <= 52) ||
|
||||||
|
(x >= 53 && x <= 70 && y >= 48 && y <= 65) ||
|
||||||
|
(x >= 66 && x <= 83 && y >= 42 && y <= 64)
|
||||||
|
) {
|
||||||
|
return 'forest';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(x >= 0 && x <= 15 && y <= 30) ||
|
||||||
|
(x >= 28 && x <= 50 && y <= 20) ||
|
||||||
|
(x >= 50 && x <= 70 && y >= 0 && y <= 22) ||
|
||||||
|
(x >= 71 && x <= 83 && y <= 13) ||
|
||||||
|
(x >= 33 && x <= 54 && y >= 58 && y <= 65)
|
||||||
|
) {
|
||||||
|
return 'hill';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(x <= 2 && y <= 57) ||
|
||||||
|
(x >= 81 && y >= 37) ||
|
||||||
|
(x >= 62 && x <= 67 && y <= 10) ||
|
||||||
|
(x >= 27 && x <= 34 && y >= 30 && y <= 46) ||
|
||||||
|
(x >= 68 && x <= 70 && y >= 47 && y <= 58)
|
||||||
|
) {
|
||||||
|
return 'cliff';
|
||||||
|
}
|
||||||
|
return 'plain';
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
|
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
|
||||||
return {
|
return {
|
||||||
...cloneUnitForScenario(unit),
|
...cloneUnitForScenario(unit),
|
||||||
|
|||||||
@@ -710,7 +710,42 @@ const unitTexture: Record<string, string> = {
|
|||||||
'fan-siege-ambusher-c': 'unit-rebel',
|
'fan-siege-ambusher-c': 'unit-rebel',
|
||||||
'fan-siege-officer-pang-de': 'unit-rebel-cavalry',
|
'fan-siege-officer-pang-de': 'unit-rebel-cavalry',
|
||||||
'fan-siege-officer-lu-meng': 'unit-rebel-leader',
|
'fan-siege-officer-lu-meng': 'unit-rebel-leader',
|
||||||
'fan-siege-leader-cao-ren': 'unit-rebel-leader'
|
'fan-siege-leader-cao-ren': 'unit-rebel-leader',
|
||||||
|
'jing-rear-scout-a': 'unit-rebel',
|
||||||
|
'jing-rear-scout-b': 'unit-rebel',
|
||||||
|
'jing-rear-scout-c': 'unit-rebel',
|
||||||
|
'jing-rear-scout-d': 'unit-rebel',
|
||||||
|
'jing-rear-scout-e': 'unit-rebel',
|
||||||
|
'jing-rear-infantry-a': 'unit-rebel',
|
||||||
|
'jing-rear-infantry-b': 'unit-rebel',
|
||||||
|
'jing-rear-infantry-c': 'unit-rebel',
|
||||||
|
'jing-rear-infantry-d': 'unit-rebel',
|
||||||
|
'jing-rear-infantry-e': 'unit-rebel',
|
||||||
|
'jing-rear-infantry-f': 'unit-rebel',
|
||||||
|
'jing-rear-archer-a': 'unit-rebel-archer',
|
||||||
|
'jing-rear-archer-b': 'unit-rebel-archer',
|
||||||
|
'jing-rear-archer-c': 'unit-rebel-archer',
|
||||||
|
'jing-rear-archer-d': 'unit-rebel-archer',
|
||||||
|
'jing-rear-archer-e': 'unit-rebel-archer',
|
||||||
|
'jing-rear-cavalry-a': 'unit-rebel-cavalry',
|
||||||
|
'jing-rear-cavalry-b': 'unit-rebel-cavalry',
|
||||||
|
'jing-rear-cavalry-c': 'unit-rebel-cavalry',
|
||||||
|
'jing-rear-cavalry-d': 'unit-rebel-cavalry',
|
||||||
|
'jing-rear-guard-a': 'unit-rebel',
|
||||||
|
'jing-rear-guard-b': 'unit-rebel',
|
||||||
|
'jing-rear-guard-c': 'unit-rebel',
|
||||||
|
'jing-rear-guard-d': 'unit-rebel',
|
||||||
|
'jing-rear-strategist-a': 'unit-rebel-archer',
|
||||||
|
'jing-rear-strategist-b': 'unit-rebel-archer',
|
||||||
|
'jing-rear-strategist-c': 'unit-rebel-archer',
|
||||||
|
'jing-rear-ambusher-a': 'unit-rebel',
|
||||||
|
'jing-rear-ambusher-b': 'unit-rebel',
|
||||||
|
'jing-rear-ambusher-c': 'unit-rebel',
|
||||||
|
'jing-rear-marine-a': 'unit-rebel',
|
||||||
|
'jing-rear-marine-b': 'unit-rebel',
|
||||||
|
'jing-rear-officer-lu-xun': 'unit-rebel-archer',
|
||||||
|
'jing-rear-officer-mi-fang': 'unit-rebel-leader',
|
||||||
|
'jing-rear-leader-lu-meng': 'unit-rebel-leader'
|
||||||
};
|
};
|
||||||
|
|
||||||
const unitTextureByClass: Partial<Record<UnitClassKey, string>> = {
|
const unitTextureByClass: Partial<Record<UnitClassKey, string>> = {
|
||||||
@@ -1878,7 +1913,42 @@ const enemyAiByUnitId: Record<string, EnemyAiBehavior> = {
|
|||||||
'fan-siege-ambusher-c': 'aggressive',
|
'fan-siege-ambusher-c': 'aggressive',
|
||||||
'fan-siege-officer-pang-de': 'aggressive',
|
'fan-siege-officer-pang-de': 'aggressive',
|
||||||
'fan-siege-officer-lu-meng': 'guard',
|
'fan-siege-officer-lu-meng': 'guard',
|
||||||
'fan-siege-leader-cao-ren': 'guard'
|
'fan-siege-leader-cao-ren': 'guard',
|
||||||
|
'jing-rear-scout-a': 'aggressive',
|
||||||
|
'jing-rear-scout-b': 'aggressive',
|
||||||
|
'jing-rear-scout-c': 'aggressive',
|
||||||
|
'jing-rear-scout-d': 'aggressive',
|
||||||
|
'jing-rear-scout-e': 'aggressive',
|
||||||
|
'jing-rear-infantry-a': 'guard',
|
||||||
|
'jing-rear-infantry-b': 'guard',
|
||||||
|
'jing-rear-infantry-c': 'guard',
|
||||||
|
'jing-rear-infantry-d': 'guard',
|
||||||
|
'jing-rear-infantry-e': 'guard',
|
||||||
|
'jing-rear-infantry-f': 'guard',
|
||||||
|
'jing-rear-archer-a': 'hold',
|
||||||
|
'jing-rear-archer-b': 'hold',
|
||||||
|
'jing-rear-archer-c': 'hold',
|
||||||
|
'jing-rear-archer-d': 'hold',
|
||||||
|
'jing-rear-archer-e': 'hold',
|
||||||
|
'jing-rear-cavalry-a': 'aggressive',
|
||||||
|
'jing-rear-cavalry-b': 'aggressive',
|
||||||
|
'jing-rear-cavalry-c': 'aggressive',
|
||||||
|
'jing-rear-cavalry-d': 'aggressive',
|
||||||
|
'jing-rear-guard-a': 'guard',
|
||||||
|
'jing-rear-guard-b': 'guard',
|
||||||
|
'jing-rear-guard-c': 'guard',
|
||||||
|
'jing-rear-guard-d': 'guard',
|
||||||
|
'jing-rear-strategist-a': 'hold',
|
||||||
|
'jing-rear-strategist-b': 'hold',
|
||||||
|
'jing-rear-strategist-c': 'hold',
|
||||||
|
'jing-rear-ambusher-a': 'aggressive',
|
||||||
|
'jing-rear-ambusher-b': 'aggressive',
|
||||||
|
'jing-rear-ambusher-c': 'aggressive',
|
||||||
|
'jing-rear-marine-a': 'aggressive',
|
||||||
|
'jing-rear-marine-b': 'guard',
|
||||||
|
'jing-rear-officer-lu-xun': 'hold',
|
||||||
|
'jing-rear-officer-mi-fang': 'guard',
|
||||||
|
'jing-rear-leader-lu-meng': 'guard'
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultEnemyAiByClass: Partial<Record<UnitClassKey, EnemyAiBehavior>> = {
|
const defaultEnemyAiByClass: Partial<Record<UnitClassKey, EnemyAiBehavior>> = {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import fifteenthBattleMapUrl from '../../assets/images/battle/fifteenth-battle-m
|
|||||||
import firstBattleMapUrl from '../../assets/images/battle/first-battle-map.png';
|
import firstBattleMapUrl from '../../assets/images/battle/first-battle-map.png';
|
||||||
import fortiethBattleMapUrl from '../../assets/images/battle/fortieth-battle-map.svg';
|
import fortiethBattleMapUrl from '../../assets/images/battle/fortieth-battle-map.svg';
|
||||||
import fortyFirstBattleMapUrl from '../../assets/images/battle/forty-first-battle-map.svg';
|
import fortyFirstBattleMapUrl from '../../assets/images/battle/forty-first-battle-map.svg';
|
||||||
|
import fortySecondBattleMapUrl from '../../assets/images/battle/forty-second-battle-map.svg';
|
||||||
import fourteenthBattleMapUrl from '../../assets/images/battle/fourteenth-battle-map.svg';
|
import fourteenthBattleMapUrl from '../../assets/images/battle/fourteenth-battle-map.svg';
|
||||||
import fourthBattleMapUrl from '../../assets/images/battle/fourth-battle-map.svg';
|
import fourthBattleMapUrl from '../../assets/images/battle/fourth-battle-map.svg';
|
||||||
import ninthBattleMapUrl from '../../assets/images/battle/ninth-battle-map.svg';
|
import ninthBattleMapUrl from '../../assets/images/battle/ninth-battle-map.svg';
|
||||||
@@ -140,6 +141,7 @@ export class BootScene extends Phaser.Scene {
|
|||||||
this.load.image('battle-map-thirty-ninth', thirtyNinthBattleMapUrl);
|
this.load.image('battle-map-thirty-ninth', thirtyNinthBattleMapUrl);
|
||||||
this.load.image('battle-map-fortieth', fortiethBattleMapUrl);
|
this.load.image('battle-map-fortieth', fortiethBattleMapUrl);
|
||||||
this.load.image('battle-map-forty-first', fortyFirstBattleMapUrl);
|
this.load.image('battle-map-forty-first', fortyFirstBattleMapUrl);
|
||||||
|
this.load.image('battle-map-forty-second', fortySecondBattleMapUrl);
|
||||||
this.load.image('portrait-liu-bei', liuBeiPortraitUrl);
|
this.load.image('portrait-liu-bei', liuBeiPortraitUrl);
|
||||||
this.load.image('portrait-guan-yu', guanYuPortraitUrl);
|
this.load.image('portrait-guan-yu', guanYuPortraitUrl);
|
||||||
this.load.image('portrait-zhang-fei', zhangFeiPortraitUrl);
|
this.load.image('portrait-zhang-fei', zhangFeiPortraitUrl);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
hanzhongScoutRecruitUnits,
|
hanzhongScoutRecruitUnits,
|
||||||
fanCastleBonds,
|
fanCastleBonds,
|
||||||
fanCastleSiegeBonds,
|
fanCastleSiegeBonds,
|
||||||
|
jingRearCrisisBonds,
|
||||||
jingDefenseBonds,
|
jingDefenseBonds,
|
||||||
jingzhouRecruitBonds,
|
jingzhouRecruitBonds,
|
||||||
jingzhouRecruitUnits,
|
jingzhouRecruitUnits,
|
||||||
@@ -357,7 +358,8 @@ const campaignTimelineChapters: CampaignTimelineChapter[] = [
|
|||||||
'thirty-eighth-battle-jing-defense',
|
'thirty-eighth-battle-jing-defense',
|
||||||
'thirty-ninth-battle-fan-castle-vanguard',
|
'thirty-ninth-battle-fan-castle-vanguard',
|
||||||
'fortieth-battle-han-river-flood',
|
'fortieth-battle-han-river-flood',
|
||||||
'forty-first-battle-fan-castle-siege'
|
'forty-first-battle-fan-castle-siege',
|
||||||
|
'forty-second-battle-jing-rear-crisis'
|
||||||
],
|
],
|
||||||
nextHints: ['왕업 선언', '번성 포위', '형주 위기']
|
nextHints: ['왕업 선언', '번성 포위', '형주 위기']
|
||||||
}
|
}
|
||||||
@@ -404,7 +406,8 @@ const campBattleIds = {
|
|||||||
thirtyEighth: 'thirty-eighth-battle-jing-defense',
|
thirtyEighth: 'thirty-eighth-battle-jing-defense',
|
||||||
thirtyNinth: 'thirty-ninth-battle-fan-castle-vanguard',
|
thirtyNinth: 'thirty-ninth-battle-fan-castle-vanguard',
|
||||||
fortieth: 'fortieth-battle-han-river-flood',
|
fortieth: 'fortieth-battle-han-river-flood',
|
||||||
fortyFirst: 'forty-first-battle-fan-castle-siege'
|
fortyFirst: 'forty-first-battle-fan-castle-siege',
|
||||||
|
fortySecond: 'forty-second-battle-jing-rear-crisis'
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const defaultRequiredSortieUnitIds = ['liu-bei'];
|
const defaultRequiredSortieUnitIds = ['liu-bei'];
|
||||||
@@ -881,6 +884,20 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
|
|||||||
{ unitId: 'ma-chao', reason: '방덕 기병과 조조군 북로 기병을 맞받아치는 강한 기병 대응 카드입니다.' }
|
{ unitId: 'ma-chao', reason: '방덕 기병과 조조군 북로 기병을 맞받아치는 강한 기병 대응 카드입니다.' }
|
||||||
],
|
],
|
||||||
note: '번성 공성전은 스물두 명 중 일곱 명만 출전합니다. 유비와 관우는 필수이며, 성벽 압박, 방덕 기병 대응, 강동 정찰 경계를 어떻게 나눌지 고르는 전투입니다.'
|
note: '번성 공성전은 스물두 명 중 일곱 명만 출전합니다. 유비와 관우는 필수이며, 성벽 압박, 방덕 기병 대응, 강동 정찰 경계를 어떻게 나눌지 고르는 전투입니다.'
|
||||||
|
},
|
||||||
|
'forty-second-battle-jing-rear-crisis': {
|
||||||
|
maxUnits: 7,
|
||||||
|
requiredUnitIds: ['liu-bei', 'guan-yu'],
|
||||||
|
recommended: [
|
||||||
|
{ unitId: 'liu-bei', reason: '형주 후방을 다독일 큰 명분과 패배 조건의 중심입니다.' },
|
||||||
|
{ unitId: 'guan-yu', reason: '번성 전선과 형주 후방을 함께 묶는 핵심 장수입니다.' },
|
||||||
|
{ unitId: 'ma-liang', reason: '강릉 나루의 민심과 강동의 말투를 읽는 현지 참모입니다.' },
|
||||||
|
{ unitId: 'mi-zhu', reason: '창고와 군량선을 지키는 보급 축이며 후방 이벤트와 잘 맞물립니다.' },
|
||||||
|
{ unitId: 'zhao-yun', reason: '나루와 창고 사이를 빠르게 보강하는 기동 축입니다.' },
|
||||||
|
{ unitId: 'huang-quan', reason: '흔들리는 장수와 포로, 장부를 신중하게 판정하는 참모입니다.' },
|
||||||
|
{ unitId: 'wang-ping', reason: '숲길과 강변 초소의 지형을 읽어 후방 기습을 막기 좋습니다.' }
|
||||||
|
],
|
||||||
|
note: '강릉 나루 경계전은 스물두 명 중 일곱 명만 출전합니다. 유비와 관우는 필수이며, 후방 창고, 강동 정찰, 숲길 기습을 어떻게 막을지 고르는 전투입니다.'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4286,6 +4303,87 @@ const campDialogues: CampDialogue[] = [
|
|||||||
rewardExp: 16
|
rewardExp: 16
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'guan-mizhu-after-jing-rear',
|
||||||
|
title: '창고를 지키는 의',
|
||||||
|
availableAfterBattleIds: [campBattleIds.fortySecond],
|
||||||
|
unitIds: ['guan-yu', 'mi-zhu'],
|
||||||
|
bondId: 'guan-yu__mi-zhu_rear',
|
||||||
|
rewardExp: 46,
|
||||||
|
lines: [
|
||||||
|
'미축: 강동의 척후가 상선으로 들어오면 창고 문을 잠그는 것만으로는 부족합니다. 장부와 사람 마음이 함께 지켜져야 합니다.',
|
||||||
|
'관우: 군량이 흔들리면 성문 앞의 칼도 가벼워지오. 그대가 창고의 말과 숫자를 붙잡아 주시오.',
|
||||||
|
'미축: 상인 명부와 군량 표식을 새로 맞추겠습니다. 후방의 믿음이 앞의 진군을 버티게 할 것입니다.'
|
||||||
|
],
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 'reset-warehouse-ledgers',
|
||||||
|
label: '창고 장부를 다시 맞춘다',
|
||||||
|
response: '미축은 창고 장부와 선박 표식을 맞추었고, 강릉 후방의 보급 불안이 줄었습니다.',
|
||||||
|
rewardExp: 17
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'watch-merchant-boats',
|
||||||
|
label: '상선 감시를 늘린다',
|
||||||
|
response: '관우군은 상선의 출입 순서를 다시 세웠고, 위장 척후가 숨어들 여지가 조금 줄었습니다.',
|
||||||
|
rewardExp: 16
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'guan-maliang-after-jing-rear',
|
||||||
|
title: '부드러운 말의 칼',
|
||||||
|
availableAfterBattleIds: [campBattleIds.fortySecond],
|
||||||
|
unitIds: ['guan-yu', 'ma-liang'],
|
||||||
|
bondId: 'guan-yu__ma-liang_rear',
|
||||||
|
rewardExp: 44,
|
||||||
|
lines: [
|
||||||
|
'마량: 육손의 글은 예를 갖췄지만 지나치게 낮았습니다. 낮은 말은 때로 칼보다 더 깊이 들어옵니다.',
|
||||||
|
'관우: 예가 지나치면 뜻을 숨기는 법이오. 강동의 말과 배를 함께 살피시오.',
|
||||||
|
'마량: 강변 마을의 소문부터 다시 모으겠습니다. 후방의 균열은 작은 말에서 시작될 때가 많습니다.'
|
||||||
|
],
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 'read-lu-xun-letter',
|
||||||
|
label: '육손의 글을 분석한다',
|
||||||
|
response: '마량은 문장의 예와 속뜻을 나누어 읽었고, 관우군은 강동의 다음 수를 더 경계하게 되었습니다.',
|
||||||
|
rewardExp: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'gather-river-rumors',
|
||||||
|
label: '강변 소문을 모은다',
|
||||||
|
response: '마량이 강변 마을의 소문을 정리하자, 나루와 창고를 잇는 경계망이 조금 더 촘촘해졌습니다.',
|
||||||
|
rewardExp: 15
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'liu-mizhu-after-jing-rear',
|
||||||
|
title: '백성과 군량',
|
||||||
|
availableAfterBattleIds: [campBattleIds.fortySecond],
|
||||||
|
unitIds: ['liu-bei', 'mi-zhu'],
|
||||||
|
bondId: 'liu-bei__mi-zhu_rear',
|
||||||
|
rewardExp: 42,
|
||||||
|
lines: [
|
||||||
|
'유비: 후방의 백성이 두려워하면 창고도 성문도 우리 편이 되지 못하오.',
|
||||||
|
'미축: 강동의 배가 물건을 싣고 와도 마음은 흔들 수 있습니다. 백성에게 먼저 설명하겠습니다.',
|
||||||
|
'유비: 군량을 지키되 백성의 삶을 누르지 마시오. 형주의 믿음을 잃으면 승리도 오래가지 못하오.'
|
||||||
|
],
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 'share-grain-with-villages',
|
||||||
|
label: '마을에 곡식을 나눈다',
|
||||||
|
response: '유비와 미축은 작은 곡식 창고를 열어 강변 마을의 불안을 달랬습니다.',
|
||||||
|
rewardExp: 15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'explain-rear-orders',
|
||||||
|
label: '후방 군령을 설명한다',
|
||||||
|
response: '미축은 군령의 이유를 상인과 백성에게 설명했고, 형주 후방의 불신이 조금 누그러졌습니다.',
|
||||||
|
rewardExp: 14
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -5875,6 +5973,66 @@ const campVisits: CampVisitDefinition[] = [
|
|||||||
itemRewards: ['콩 12']
|
itemRewards: ['콩 12']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'jing-rear-warehouse-ledgers',
|
||||||
|
title: '강릉 창고 장부 대조',
|
||||||
|
location: '강릉 동쪽 창고',
|
||||||
|
availableAfterBattleIds: [campBattleIds.fortySecond],
|
||||||
|
bondId: 'guan-yu__mi-zhu_rear',
|
||||||
|
description: '관우와 미축이 강릉 창고의 장부와 상선 출입 표식을 대조하며, 위장 척후가 남긴 빈틈을 찾습니다.',
|
||||||
|
lines: [
|
||||||
|
'미축: 숫자는 거짓말을 못하지만, 숫자를 적는 사람은 흔들릴 수 있습니다. 장부의 빈칸이 수상합니다.',
|
||||||
|
'관우: 창고 문을 지키는 병사만 탓할 일이 아니오. 절차를 바꾸고 다시 익히게 하시오.',
|
||||||
|
'창고 관리들은 상선 표식과 곡식 자루 수를 다시 맞췄고, 병사들은 밤 출입 순서를 새로 배웠습니다.'
|
||||||
|
],
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 'audit-warehouse-marks',
|
||||||
|
label: '상선 표식을 대조한다',
|
||||||
|
response: '상선 표식이 정리되어 강동 척후가 같은 길로 다시 숨어들기 어려워졌습니다.',
|
||||||
|
bondExp: 36,
|
||||||
|
itemRewards: ['강릉 창고 장부 1']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'seal-night-storehouses',
|
||||||
|
label: '야간 창고를 봉한다',
|
||||||
|
response: '밤 창고 출입이 제한되며 군량 손실이 줄고, 병사들의 경계 순서가 분명해졌습니다.',
|
||||||
|
bondExp: 34,
|
||||||
|
gold: 940,
|
||||||
|
itemRewards: ['콩 14']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'jing-rear-river-rumors',
|
||||||
|
title: '강변 소문 수집',
|
||||||
|
location: '강릉 동쪽 나루 마을',
|
||||||
|
availableAfterBattleIds: [campBattleIds.fortySecond],
|
||||||
|
bondId: 'guan-yu__ma-liang_rear',
|
||||||
|
description: '관우와 마량이 나루 마을을 돌아보며, 강동의 문서와 상선이 남긴 말의 흐름을 모읍니다.',
|
||||||
|
lines: [
|
||||||
|
'마량: 배는 물길을 따라 오지만, 소문은 사람의 마음을 따라 먼저 들어옵니다.',
|
||||||
|
'관우: 성문 앞에서 이긴 뒤 백성의 귀를 잃으면 큰일이오. 작은 말도 모두 적어 두시오.',
|
||||||
|
'마을 어른들은 낯선 상인의 말투와 가격 변화를 조심스럽게 전했고, 정찰병은 나루 신호를 다시 맞췄습니다.'
|
||||||
|
],
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 'map-rumor-routes',
|
||||||
|
label: '소문의 길을 표시한다',
|
||||||
|
response: '마량은 소문이 퍼지는 길을 지도에 적었고, 강동의 다음 침투 후보지가 조금 더 선명해졌습니다.',
|
||||||
|
bondExp: 36,
|
||||||
|
itemRewards: ['강동 정찰 기록 1']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'reassure-river-elders',
|
||||||
|
label: '마을 어른을 안심시킨다',
|
||||||
|
response: '관우군은 백성을 압박하지 않겠다고 약속했고, 나루 마을의 경계심이 조금 누그러졌습니다.',
|
||||||
|
bondExp: 34,
|
||||||
|
gold: 980,
|
||||||
|
itemRewards: ['상처약 5']
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -5961,7 +6119,7 @@ export class CampScene extends Phaser.Scene {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (battleId === campBattleIds.fortieth || battleId === campBattleIds.fortyFirst) {
|
if (battleId === campBattleIds.fortieth || battleId === campBattleIds.fortyFirst || battleId === campBattleIds.fortySecond) {
|
||||||
this.campaign = ensureCampaignRosterUnits(
|
this.campaign = ensureCampaignRosterUnits(
|
||||||
[
|
[
|
||||||
...xuzhouRecruitUnits,
|
...xuzhouRecruitUnits,
|
||||||
@@ -6004,7 +6162,8 @@ export class CampScene extends Phaser.Scene {
|
|||||||
...jingDefenseBonds,
|
...jingDefenseBonds,
|
||||||
...fanCastleBonds,
|
...fanCastleBonds,
|
||||||
...hanRiverFloodBonds,
|
...hanRiverFloodBonds,
|
||||||
...fanCastleSiegeBonds
|
...fanCastleSiegeBonds,
|
||||||
|
...jingRearCrisisBonds
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
this.report = this.campaign.firstBattleReport ?? this.report;
|
this.report = this.campaign.firstBattleReport ?? this.report;
|
||||||
@@ -6639,6 +6798,9 @@ export class CampScene extends Phaser.Scene {
|
|||||||
if (this.campaign?.step === 'hanzhong-king-camp') {
|
if (this.campaign?.step === 'hanzhong-king-camp') {
|
||||||
return '한중왕 즉위 준비 군영';
|
return '한중왕 즉위 준비 군영';
|
||||||
}
|
}
|
||||||
|
if (battleId === campBattleIds.fortySecond) {
|
||||||
|
return '강릉 나루 경계전 후 군영';
|
||||||
|
}
|
||||||
if (battleId === campBattleIds.fortyFirst) {
|
if (battleId === campBattleIds.fortyFirst) {
|
||||||
return '번성 공성전 후 군영';
|
return '번성 공성전 후 군영';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
eleventhBattleScenario,
|
eleventhBattleScenario,
|
||||||
fortiethBattleScenario,
|
fortiethBattleScenario,
|
||||||
fortyFirstBattleScenario,
|
fortyFirstBattleScenario,
|
||||||
|
fortySecondBattleScenario,
|
||||||
fifthBattleScenario,
|
fifthBattleScenario,
|
||||||
fifteenthBattleScenario,
|
fifteenthBattleScenario,
|
||||||
fourteenthBattleScenario,
|
fourteenthBattleScenario,
|
||||||
@@ -382,6 +383,7 @@ export class TitleScene extends Phaser.Scene {
|
|||||||
campaign.step === 'thirty-ninth-camp' ||
|
campaign.step === 'thirty-ninth-camp' ||
|
||||||
campaign.step === 'fortieth-camp' ||
|
campaign.step === 'fortieth-camp' ||
|
||||||
campaign.step === 'forty-first-camp' ||
|
campaign.step === 'forty-first-camp' ||
|
||||||
|
campaign.step === 'forty-second-camp' ||
|
||||||
campaign.step === 'hanzhong-king-camp' ||
|
campaign.step === 'hanzhong-king-camp' ||
|
||||||
campaign.step === 'shu-han-foundation-camp'
|
campaign.step === 'shu-han-foundation-camp'
|
||||||
) {
|
) {
|
||||||
@@ -594,6 +596,11 @@ export class TitleScene extends Phaser.Scene {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (campaign.step === 'forty-second-battle') {
|
||||||
|
this.scene.start('BattleScene', { battleId: fortySecondBattleScenario.id });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (campaign.step === 'first-victory-story') {
|
if (campaign.step === 'first-victory-story') {
|
||||||
this.scene.start('StoryScene', { pages: firstBattleVictoryPages, nextScene: 'TitleScene' });
|
this.scene.start('StoryScene', { pages: firstBattleVictoryPages, nextScene: 'TitleScene' });
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ export type CampaignStep =
|
|||||||
| 'fortieth-camp'
|
| 'fortieth-camp'
|
||||||
| 'forty-first-battle'
|
| 'forty-first-battle'
|
||||||
| 'forty-first-camp'
|
| 'forty-first-camp'
|
||||||
|
| 'forty-second-battle'
|
||||||
|
| 'forty-second-camp'
|
||||||
| 'hanzhong-king-camp'
|
| 'hanzhong-king-camp'
|
||||||
| 'shu-han-foundation-camp';
|
| 'shu-han-foundation-camp';
|
||||||
|
|
||||||
@@ -228,7 +230,8 @@ const campaignBattleSteps: Record<string, { victory: CampaignStep; retry: Campai
|
|||||||
'thirty-eighth-battle-jing-defense': { victory: 'thirty-eighth-camp', retry: 'thirty-eighth-battle' },
|
'thirty-eighth-battle-jing-defense': { victory: 'thirty-eighth-camp', retry: 'thirty-eighth-battle' },
|
||||||
'thirty-ninth-battle-fan-castle-vanguard': { victory: 'thirty-ninth-camp', retry: 'thirty-ninth-battle' },
|
'thirty-ninth-battle-fan-castle-vanguard': { victory: 'thirty-ninth-camp', retry: 'thirty-ninth-battle' },
|
||||||
'fortieth-battle-han-river-flood': { victory: 'fortieth-camp', retry: 'fortieth-battle' },
|
'fortieth-battle-han-river-flood': { victory: 'fortieth-camp', retry: 'fortieth-battle' },
|
||||||
'forty-first-battle-fan-castle-siege': { victory: 'forty-first-camp', retry: 'forty-first-battle' }
|
'forty-first-battle-fan-castle-siege': { victory: 'forty-first-camp', retry: 'forty-first-battle' },
|
||||||
|
'forty-second-battle-jing-rear-crisis': { victory: 'forty-second-camp', retry: 'forty-second-battle' }
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CampaignSaveSlotSummary = {
|
export type CampaignSaveSlotSummary = {
|
||||||
|
|||||||
Reference in New Issue
Block a user