Add sixth Meng Huo capture battle

This commit is contained in:
2026-06-24 00:09:17 +09:00
parent 189766491f
commit a54e852c2b
11 changed files with 867 additions and 62 deletions

View File

@@ -4,6 +4,7 @@ import eleventhBattleMapUrl from '../../assets/images/battle/eleventh-battle-map
import fiftiethBattleMapUrl from '../../assets/images/battle/fiftieth-battle-map.svg';
import fiftyFirstBattleMapUrl from '../../assets/images/battle/fifty-first-battle-map.svg';
import fiftySecondBattleMapUrl from '../../assets/images/battle/fifty-second-battle-map.svg';
import fiftyThirdBattleMapUrl from '../../assets/images/battle/fifty-third-battle-map.svg';
import fifthBattleMapUrl from '../../assets/images/battle/fifth-battle-map.svg';
import fifteenthBattleMapUrl from '../../assets/images/battle/fifteenth-battle-map.svg';
import firstBattleMapUrl from '../../assets/images/battle/first-battle-map.png';
@@ -103,5 +104,6 @@ export const battleMapAssets: Record<string, string> = {
'battle-map-forty-ninth': fortyNinthBattleMapUrl,
'battle-map-fiftieth': fiftiethBattleMapUrl,
'battle-map-fifty-first': fiftyFirstBattleMapUrl,
'battle-map-fifty-second': fiftySecondBattleMapUrl
'battle-map-fifty-second': fiftySecondBattleMapUrl,
'battle-map-fifty-third': fiftyThirdBattleMapUrl
};

View File

@@ -11,6 +11,10 @@ import {
fiftySecondBattleMap,
fiftySecondBattleUnits,
fiftySecondBattleVictoryPages,
fiftyThirdBattleBonds,
fiftyThirdBattleMap,
fiftyThirdBattleUnits,
fiftyThirdBattleVictoryPages,
firstBattleBonds,
fifteenthBattleBonds,
fifteenthBattleMap,
@@ -265,7 +269,8 @@ export type BattleScenarioId =
| 'forty-ninth-battle-meng-huo-second-capture'
| 'fiftieth-battle-meng-huo-third-capture'
| 'fifty-first-battle-meng-huo-fourth-capture'
| 'fifty-second-battle-meng-huo-fifth-capture';
| 'fifty-second-battle-meng-huo-fifth-capture'
| 'fifty-third-battle-meng-huo-sixth-capture';
export type BattleObjectiveKind = 'defeat-leader' | 'pacify-leader' | 'keep-unit-alive' | 'secure-terrain' | 'quick-victory';
@@ -3391,6 +3396,73 @@ export const fiftySecondBattleScenario: BattleScenarioDefinition = {
nextCampScene: 'CampScene'
};
export const fiftyThirdBattleScenario: BattleScenarioDefinition = {
id: 'fifty-third-battle-meng-huo-sixth-capture',
title: '칠종칠금 6차전',
victoryConditionLabel: '맹획 여섯 번째 생포와 마을 신뢰 유지',
defeatConditionLabel: '제갈량 퇴각',
openingObjectiveLines: [
'맹획은 남은 자존심을 내세워 깊은 계곡의 부족들을 다시 불러 모았습니다. 이번 전투는 적 본영을 누르면서도 마을 신뢰를 깨뜨리지 않는 것이 핵심입니다.',
'강경파 잔당은 신뢰 장부와 계곡 퇴로를 동시에 흔들려 합니다. 마을, 길목, 요새를 함께 지키면 마지막 설득으로 이어질 근거가 생깁니다.',
'제갈량은 반드시 생존해야 합니다. 마량과 황권으로 말과 장부를 남기고, 왕평과 마대로 계곡 길을 지키며, 조운과 위연으로 잔당 추격을 끊으십시오.'
],
map: fiftyThirdBattleMap,
units: fiftyThirdBattleUnits,
bonds: fiftyThirdBattleBonds,
mapTextureKey: 'battle-map-fifty-third',
leaderUnitId: 'menghuo-sixth-leader',
quickVictoryTurnLimit: 102,
baseVictoryGold: 13620,
objectives: [
{
id: 'pacify-meng-huo-sixth',
kind: 'pacify-leader',
label: '맹획 여섯 번째 생포',
rewardGold: 9180,
unitId: 'menghuo-sixth-leader'
},
{
id: 'zhuge-liang',
kind: 'keep-unit-alive',
label: '제갈량 생존',
rewardGold: 2320,
unitId: 'zhuge-liang'
},
{
id: 'trust-road',
kind: 'secure-terrain',
label: '신뢰 퇴로 확보',
rewardGold: 4560,
terrain: 'road'
},
{
id: 'village-trust',
kind: 'secure-terrain',
label: '마을 신뢰 유지',
rewardGold: 4240,
terrain: 'village'
},
{
id: 'hardliner-remnants',
kind: 'secure-terrain',
label: '강경파 잔당 요새 제압',
rewardGold: 4040,
terrain: 'fort'
},
{
id: 'quick',
kind: 'quick-victory',
label: '102턴 이내 여섯 번째 생포',
rewardGold: 3060,
maxTurn: 102
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 74', '상처약 58', '탁주 26', '남중 신뢰 장부 1', '계곡 회유 표식 1'],
victoryPages: fiftyThirdBattleVictoryPages,
nextCampScene: 'CampScene'
};
export const defaultBattleScenarioId: BattleScenarioId = firstBattleScenario.id;
export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition> = {
@@ -3445,7 +3517,8 @@ export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition>
'forty-ninth-battle-meng-huo-second-capture': fortyNinthBattleScenario,
'fiftieth-battle-meng-huo-third-capture': fiftiethBattleScenario,
'fifty-first-battle-meng-huo-fourth-capture': fiftyFirstBattleScenario,
'fifty-second-battle-meng-huo-fifth-capture': fiftySecondBattleScenario
'fifty-second-battle-meng-huo-fifth-capture': fiftySecondBattleScenario,
'fifty-third-battle-meng-huo-sixth-capture': fiftyThirdBattleScenario
};
export const defaultBattleScenario = battleScenarios[defaultBattleScenarioId];

View File

@@ -7,6 +7,7 @@ import {
fiftiethBattleScenario,
fiftyFirstBattleScenario,
fiftySecondBattleScenario,
fiftyThirdBattleScenario,
fortiethBattleScenario,
fortyFirstBattleScenario,
fortySecondBattleScenario,
@@ -68,6 +69,8 @@ import {
fiftyFirstBattleVictoryPages,
fiftySecondBattleIntroPages,
fiftySecondBattleVictoryPages,
fiftyThirdBattleIntroPages,
fiftyThirdBattleVictoryPages,
fortiethBattleIntroPages,
fortiethBattleVictoryPages,
fortyFirstBattleIntroPages,
@@ -759,13 +762,24 @@ const sortieFlows: Record<string, SortieFlow> = {
},
[fiftySecondBattleScenario.id]: {
afterBattleId: fiftySecondBattleScenario.id,
eyebrow: '다음 장 준비',
title: '여섯 번째 회유의 길',
eyebrow: '다음 장',
title: fiftyThirdBattleScenario.title,
description:
'맹획은 다섯 번째로 붙잡혔고, 강경파 호족과 물러선 호족의 말이 갈라졌습니다. 다음 장에서는 남중의 자존심을 더 직접적으로 마주하면서도, 지난 회유의 약속을 무너뜨리지 않는 길을 준비합니다.',
rewardHint: '다음 장: 칠종칠금 6차전과 마지막 설득 준비 중',
pages: fiftySecondBattleVictoryPages,
unavailableNotice: '칠종칠금 6차전은 다음 작업에서 이어집니다. 지금은 다섯 번째 생포 뒤의 강경파 분리 장부와 회유 깃발을 정비할 수 있습니다.'
'맹획은 다섯 번째로 붙잡혔고, 강경파 호족과 물러선 호족의 말이 갈라졌습니다. 이제 남중의 자존심을 더 직접적으로 마주하면서도, 지난 회유의 약속을 무너뜨리지 않는 여섯 번째 길을 엽니다.',
rewardHint: `예상 보상: ${fiftyThirdBattleScenario.title} 개방 / 남중 신뢰 장부`,
nextBattleId: fiftyThirdBattleScenario.id,
campaignStep: 'fifty-third-battle',
pages: [...fiftySecondBattleVictoryPages, ...fiftyThirdBattleIntroPages]
},
[fiftyThirdBattleScenario.id]: {
afterBattleId: fiftyThirdBattleScenario.id,
eyebrow: '다음 장 준비',
title: '칠종칠금의 마지막 문턱',
description:
'맹획은 여섯 번째로 붙잡혔고, 남중의 마을들은 촉한군의 약속을 직접 보았습니다. 다음 장에서는 칠종칠금의 마지막 설득과 남중 안정의 결말을 준비합니다.',
rewardHint: '다음 장: 칠종칠금 7차전과 남중 완전 회유 준비 중',
pages: fiftyThirdBattleVictoryPages,
unavailableNotice: '칠종칠금 7차전은 다음 작업에서 이어집니다. 지금은 여섯 번째 생포 뒤의 신뢰 장부와 계곡 회유 표식을 정비할 수 있습니다.'
}
};

View File

@@ -3403,6 +3403,59 @@ export const fiftySecondBattleVictoryPages: StoryPage[] = [
}
];
export const fiftyThirdBattleIntroPages: StoryPage[] = [
{
id: 'fifty-third-pride-remains',
bgm: 'story-dark',
chapter: '남은 자존심',
background: 'story-militia',
speaker: '마량',
text: '다섯 번째 생포 뒤 강경파와 물러설 호족의 말이 갈라졌습니다. 그러나 맹획은 아직 남중의 자존심을 내세우며, 마지막으로 깊은 계곡의 부족들을 불러 모았습니다.'
},
{
id: 'fifty-third-sixth-capture-plan',
bgm: 'battle-prep',
chapter: '여섯 번째 생포',
background: 'story-three-heroes',
speaker: '제갈량',
text: '이번에는 적을 밀어붙이는 힘보다 멈춰 설 줄 아는 군율이 중요합니다. 마을 신뢰를 지키고 강경파 잔당의 길을 끊되, 맹획에게 남중 전체가 더는 같은 마음이 아님을 보이십시오.'
},
{
id: 'fifty-third-sortie',
bgm: 'battle-prep',
chapter: '칠종칠금 6차전',
background: 'story-sortie',
speaker: '황권',
text: '계곡 길은 넓어 보이나 물길과 절벽이 칼처럼 갈라져 있습니다. 장부를 들 장수, 산길을 지킬 장수, 추격을 멈출 장수를 따로 세워야 여섯 번째 생포가 설득으로 남습니다.'
}
];
export const fiftyThirdBattleVictoryPages: StoryPage[] = [
{
id: 'fifty-third-victory-sixth-capture',
bgm: 'militia-theme',
chapter: '여섯 번째 생포',
background: 'story-sortie',
text: '맹획은 여섯 번째로 붙잡혔고, 깊은 계곡의 부족들은 촉한군이 강경파 잔당을 누르면서도 마을을 함부로 밟지 않는 모습을 보았습니다.'
},
{
id: 'fifty-third-victory-trust-ledger',
bgm: 'story-dark',
chapter: '신뢰의 장부',
background: 'story-militia',
speaker: '마량',
text: '처음에는 두려워 숨던 촌장들이 이제는 직접 이름을 말했습니다. 두려움의 장부가 아니라 신뢰의 장부가 만들어졌으니, 마지막 설득의 말도 조금은 닿을 수 있습니다.'
},
{
id: 'fifty-third-next-final-capture',
bgm: 'story-dark',
chapter: '마지막 설득 앞',
background: 'story-three-heroes',
speaker: '제갈량',
text: '여섯 번 잡고도 맹획은 쉽게 항복하지 않을 것입니다. 그러나 이제 남중의 눈은 맹획의 고집뿐 아니라 촉한군의 약속도 함께 보고 있습니다. 다음은 칠종칠금의 마지막 문턱입니다.'
}
];
export const firstBattleMap: BattleMap = {
width: 20,
height: 18,
@@ -3860,6 +3913,12 @@ export const fiftySecondBattleMap: BattleMap = {
terrain: createFiftySecondBattleTerrain()
};
export const fiftyThirdBattleMap: BattleMap = {
width: 106,
height: 88,
terrain: createFiftyThirdBattleTerrain()
};
export const firstBattleUnits: UnitData[] = [
{
id: 'liu-bei',
@@ -16334,6 +16393,95 @@ export const fiftySecondBattleUnits: UnitData[] = [
createThirtyFirstEnemyUnit('menghuo-fifth-leader', '맹획', '남만왕', 'rebelLeader', 162, 1100, 270, 98, 45)
];
const fiftyThirdBattleAllyPositions: Record<string, { x: number; y: number }> = {
'guan-yu': { x: 16, y: 67 },
'zhang-fei': { x: 21, y: 69 },
'jian-yong': { x: 12, y: 74 },
'mi-zhu': { x: 14, y: 72 },
'sun-qian': { x: 18, y: 76 },
'zhao-yun': { x: 26, y: 64 },
'zhuge-liang': { x: 15, y: 64 },
'ma-liang': { x: 19, y: 61 },
'yi-ji': { x: 12, y: 79 },
'gong-zhi': { x: 22, y: 77 },
'huang-zhong': { x: 29, y: 65 },
'wei-yan': { x: 34, y: 69 },
'pang-tong': { x: 17, y: 58 },
'fa-zheng': { x: 23, y: 59 },
'wu-yi': { x: 36, y: 74 },
'yan-yan': { x: 39, y: 67 },
'li-yan': { x: 28, y: 57 },
'huang-quan': { x: 12, y: 62 },
'ma-chao': { x: 41, y: 64 },
'ma-dai': { x: 44, y: 69 },
'wang-ping': { x: 31, y: 60 }
};
export const fiftyThirdBattleUnits: UnitData[] = [
...[
...firstBattleUnits.filter((unit) => unit.faction === 'ally' && unit.id !== 'liu-bei'),
...xuzhouRecruitUnits,
...caoBreakRecruitUnits,
...liuBiaoRecruitUnits,
...zhugeRecruitUnits,
...jingzhouRecruitUnits,
...guiyangRecruitUnits,
...wulingRecruitUnits,
...changshaRecruitUnits,
...yizhouRecruitUnits,
...fuPassRecruitUnits,
...luoCastleRecruitUnits,
...luoCastleProperRecruitUnits,
...chengduPressureRecruitUnits,
...chengduSurrenderRecruitUnits,
...hanzhongOpeningRecruitUnits,
...hanzhongScoutRecruitUnits,
...hanzhongMainRecruitUnits
].map((unit) => placeScenarioUnit(unit, fiftyThirdBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })),
createThirtyFirstEnemyUnit('menghuo-sixth-scout-a', '남중 잔심 척후', '서쪽 계곡 정찰', 'bandit', 160, 716, 214, 48, 40),
createThirtyFirstEnemyUnit('menghuo-sixth-scout-b', '남중 잔심 척후', '물길 정찰', 'bandit', 160, 716, 214, 64, 38),
createThirtyFirstEnemyUnit('menghuo-sixth-scout-c', '남중 잔심 척후', '마을 감시', 'bandit', 161, 724, 216, 80, 55),
createThirtyFirstEnemyUnit('menghuo-sixth-scout-d', '남중 잔심 척후', '동쪽 절벽 감시', 'bandit', 161, 724, 216, 96, 70),
createThirtyFirstEnemyUnit('menghuo-sixth-scout-e', '남중 잔심 척후', '북쪽 산문 감시', 'bandit', 162, 732, 218, 57, 28),
createThirtyFirstEnemyUnit('menghuo-sixth-scout-f', '남중 잔심 척후', '신뢰로 감시', 'bandit', 162, 732, 218, 72, 76),
createThirtyFirstEnemyUnit('menghuo-sixth-vine-a', '잔당 등갑병', '계곡 등갑병', 'yellowTurban', 161, 1002, 252, 54, 49),
createThirtyFirstEnemyUnit('menghuo-sixth-vine-b', '잔당 등갑병', '불씨 등갑병', 'yellowTurban', 162, 1014, 254, 67, 52),
createThirtyFirstEnemyUnit('menghuo-sixth-vine-c', '잔당 등갑병', '마을 등갑병', 'yellowTurban', 162, 1014, 254, 80, 62),
createThirtyFirstEnemyUnit('menghuo-sixth-vine-d', '잔당 등갑병', '본영 등갑병', 'yellowTurban', 163, 1026, 256, 92, 54),
createThirtyFirstEnemyUnit('menghuo-sixth-vine-e', '잔당 등갑병', '후위 등갑병', 'yellowTurban', 163, 1026, 256, 100, 46),
createThirtyFirstEnemyUnit('menghuo-sixth-vine-f', '잔당 등갑병', '산문 등갑병', 'yellowTurban', 164, 1038, 258, 88, 35),
createThirtyFirstEnemyUnit('menghuo-sixth-archer-a', '남만 절벽 궁병', '독천 궁병', 'archer', 160, 768, 226, 50, 32),
createThirtyFirstEnemyUnit('menghuo-sixth-archer-b', '남만 절벽 궁병', '절벽 궁병', 'archer', 161, 776, 228, 66, 30),
createThirtyFirstEnemyUnit('menghuo-sixth-archer-c', '남만 절벽 궁병', '마을 궁병', 'archer', 161, 776, 228, 78, 48),
createThirtyFirstEnemyUnit('menghuo-sixth-archer-d', '남만 절벽 궁병', '물길 궁병', 'archer', 162, 784, 230, 90, 66),
createThirtyFirstEnemyUnit('menghuo-sixth-archer-e', '남만 절벽 궁병', '본영 궁병', 'archer', 162, 784, 230, 99, 59),
createThirtyFirstEnemyUnit('menghuo-sixth-beast-a', '남만 맹수 결사대', '강가 맹수대', 'cavalry', 162, 1018, 256, 60, 42),
createThirtyFirstEnemyUnit('menghuo-sixth-beast-b', '남만 맹수 결사대', '물길 맹수대', 'cavalry', 162, 1018, 256, 73, 44),
createThirtyFirstEnemyUnit('menghuo-sixth-beast-c', '남만 맹수 결사대', '산채 맹수대', 'cavalry', 163, 1030, 258, 85, 57),
createThirtyFirstEnemyUnit('menghuo-sixth-beast-d', '남만 맹수 결사대', '추격 맹수대', 'cavalry', 163, 1030, 258, 97, 63),
createThirtyFirstEnemyUnit('menghuo-sixth-beast-e', '남만 맹수 결사대', '신뢰로 차단대', 'cavalry', 164, 1042, 260, 71, 72),
createThirtyFirstEnemyUnit('menghuo-sixth-ambusher-a', '잔당 매복병', '계곡 매복병', 'bandit', 161, 736, 220, 41, 55),
createThirtyFirstEnemyUnit('menghuo-sixth-ambusher-b', '잔당 매복병', '숲속 매복병', 'bandit', 162, 744, 222, 57, 58),
createThirtyFirstEnemyUnit('menghuo-sixth-ambusher-c', '잔당 매복병', '강가 매복병', 'bandit', 162, 744, 222, 70, 71),
createThirtyFirstEnemyUnit('menghuo-sixth-ambusher-d', '잔당 매복병', '후방 차단대', 'bandit', 163, 752, 224, 90, 78),
createThirtyFirstEnemyUnit('menghuo-sixth-ambusher-e', '잔당 매복병', '서쪽 차단대', 'bandit', 163, 752, 224, 36, 68),
createThirtyFirstEnemyUnit('menghuo-sixth-ambusher-f', '잔당 매복병', '신뢰로 감시대', 'bandit', 164, 760, 226, 77, 76),
createThirtyFirstEnemyUnit('menghuo-sixth-guard-a', '맹획 육차 친위', '포로장 친위대', 'yellowTurban', 164, 1054, 262, 74, 46),
createThirtyFirstEnemyUnit('menghuo-sixth-guard-b', '맹획 육차 친위', '산채 친위대', 'yellowTurban', 164, 1054, 262, 87, 52),
createThirtyFirstEnemyUnit('menghuo-sixth-guard-c', '맹획 육차 친위', '본영 친위대', 'yellowTurban', 165, 1066, 264, 98, 49),
createThirtyFirstEnemyUnit('menghuo-sixth-guard-d', '맹획 육차 친위', '계곡 친위대', 'yellowTurban', 165, 1066, 264, 93, 39),
createThirtyFirstEnemyUnit('menghuo-sixth-shaman-a', '깊은 독천 제사장', '물길 제사장', 'strategist', 163, 816, 238, 66, 40),
createThirtyFirstEnemyUnit('menghuo-sixth-shaman-b', '깊은 독천 제사장', '강가 제사장', 'strategist', 164, 824, 240, 81, 53),
createThirtyFirstEnemyUnit('menghuo-sixth-shaman-c', '깊은 독천 제사장', '산채 제사장', 'strategist', 164, 824, 240, 92, 42),
createThirtyFirstEnemyUnit('menghuo-sixth-shaman-d', '깊은 독천 제사장', '계곡 제사장', 'strategist', 165, 832, 242, 86, 61),
createThirtyFirstEnemyUnit('menghuo-sixth-officer-zhurong', '축융 부인', '남중 화전장', 'rebelLeader', 166, 1098, 272, 84, 69),
createThirtyFirstEnemyUnit('menghuo-sixth-officer-mulu', '목록대왕', '맹수대왕', 'rebelLeader', 166, 1098, 272, 90, 41),
createThirtyFirstEnemyUnit('menghuo-sixth-officer-duosi', '타사대왕', '독천 호족장', 'rebelLeader', 165, 1078, 266, 74, 64),
createThirtyFirstEnemyUnit('menghuo-sixth-officer-mengyou', '맹우', '맹획의 아우', 'rebelLeader', 165, 1078, 266, 70, 56),
createThirtyFirstEnemyUnit('menghuo-sixth-officer-dailai', '대래동주', '깊은 산채 호족', 'rebelLeader', 165, 1078, 266, 83, 71),
createThirtyFirstEnemyUnit('menghuo-sixth-leader', '맹획', '남만왕', 'rebelLeader', 168, 1140, 280, 100, 47)
];
export const firstBattleBonds: BattleBond[] = [
{
id: 'liu-bei__guan-yu',
@@ -17327,6 +17475,35 @@ export const mengHuoFifthCaptureBonds: BattleBond[] = [
export const fiftySecondBattleBonds: BattleBond[] = [...fiftyFirstBattleBonds, ...mengHuoFifthCaptureBonds].map(
cloneBattleBondForScenario
);
export const mengHuoSixthCaptureBonds: BattleBond[] = [
{
id: 'zhuge-liang__ma-liang_sixth-capture',
unitIds: ['zhuge-liang', 'ma-liang'],
title: '자존심을 남기는 말',
level: 55,
exp: 0,
description: '제갈량의 큰 회유와 마량의 부드러운 말은 맹획의 체면을 완전히 짓밟지 않으면서도 남중의 마음을 돌린다.'
},
{
id: 'huang-quan__wang-ping_sixth-capture',
unitIds: ['huang-quan', 'wang-ping'],
title: '신뢰 장부와 계곡 길',
level: 51,
exp: 0,
description: '황권이 신뢰 장부를 정리하고 왕평이 계곡 퇴로를 지키면, 여섯 번째 생포도 보복이 아니라 약속으로 남는다.'
},
{
id: 'zhao-yun__wei-yan_sixth-capture',
unitIds: ['zhao-yun', 'wei-yan'],
title: '빠른 차단과 절제',
level: 47,
exp: 0,
description: '조운의 깨끗한 기동과 위연의 거친 돌파가 균형을 맞추면, 잔당 추격을 막으면서도 마을 신뢰를 잃지 않는다.'
}
];
export const fiftyThirdBattleBonds: BattleBond[] = [...fiftySecondBattleBonds, ...mengHuoSixthCaptureBonds].map(
cloneBattleBondForScenario
);
function createEighthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 22 }, (_, y) =>
@@ -20041,6 +20218,80 @@ function createFiftySecondBattleTerrain(): TerrainType[][] {
);
}
function createFiftyThirdBattleTerrain(): TerrainType[][] {
return Array.from({ length: 88 }, (_, y) =>
Array.from({ length: 106 }, (_, x): TerrainType => {
if (
(x >= 0 && x <= 105 && y >= 80) ||
(x >= 67 && x <= 73 && y >= 0 && y <= 82) ||
(x >= 6 && x <= 34 && y >= 71 && y <= 87) ||
(x >= 80 && x <= 98 && y >= 62 && y <= 80)
) {
return 'river';
}
if (
(x >= 10 && x <= 101 && y >= 67 && y <= 73) ||
(x >= 29 && x <= 78 && y >= 45 && y <= 52) ||
(x >= 74 && x <= 101 && y >= 37 && y <= 43) ||
(x >= 40 && x <= 49 && y >= 42 && y <= 76) ||
(x >= 80 && x <= 86 && y >= 51 && y <= 84) ||
(x >= 18 && x <= 54 && y >= 59 && y <= 63) ||
(x >= 53 && x <= 67 && y >= 54 && y <= 59)
) {
return 'road';
}
if (
(x >= 18 && x <= 76 && y >= 22 && y <= 78) ||
(x >= 57 && x <= 100 && y >= 30 && y <= 74) ||
(x >= 2 && x <= 41 && y >= 52 && y <= 78) ||
(x >= 82 && x <= 105 && y >= 44 && y <= 77)
) {
return 'forest';
}
if (
(x >= 0 && x <= 33 && y <= 41) ||
(x >= 35 && x <= 72 && y <= 31) ||
(x >= 75 && x <= 105 && y <= 40) ||
(x >= 90 && x <= 105 && y >= 36 && y <= 59)
) {
return 'hill';
}
if (
(x <= 2 && y <= 78) ||
(x >= 103 && y <= 74) ||
(x >= 32 && x <= 38 && y >= 0 && y <= 43) ||
(x >= 72 && x <= 78 && y >= 0 && y <= 37) ||
(x >= 46 && x <= 52 && y >= 68 && y <= 87)
) {
return 'cliff';
}
if (
(x >= 12 && x <= 28 && y >= 63 && y <= 75) ||
(x >= 41 && x <= 58 && y >= 46 && y <= 60) ||
(x >= 79 && x <= 95 && y >= 52 && y <= 65) ||
(x >= 84 && x <= 98 && y >= 35 && y <= 47)
) {
return 'village';
}
if (
(x >= 25 && x <= 40 && y >= 55 && y <= 66) ||
(x >= 67 && x <= 82 && y >= 60 && y <= 72) ||
(x >= 85 && x <= 100 && y >= 42 && y <= 55)
) {
return 'camp';
}
if (
(x >= 49 && x <= 67 && y >= 34 && y <= 45) ||
(x >= 76 && x <= 97 && y >= 34 && y <= 48) ||
(x >= 88 && x <= 101 && y >= 46 && y <= 58)
) {
return 'fort';
}
return 'plain';
})
);
}
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
return {
...cloneUnitForScenario(unit),