Add fifth Meng Huo capture battle

This commit is contained in:
2026-06-23 23:38:57 +09:00
parent b56f613e9f
commit 189766491f
11 changed files with 867 additions and 63 deletions

View File

@@ -3,6 +3,7 @@ import eighteenthBattleMapUrl from '../../assets/images/battle/eighteenth-battle
import eleventhBattleMapUrl from '../../assets/images/battle/eleventh-battle-map.svg';
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 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';
@@ -101,5 +102,6 @@ export const battleMapAssets: Record<string, string> = {
'battle-map-forty-eighth': fortyEighthBattleMapUrl,
'battle-map-forty-ninth': fortyNinthBattleMapUrl,
'battle-map-fiftieth': fiftiethBattleMapUrl,
'battle-map-fifty-first': fiftyFirstBattleMapUrl
'battle-map-fifty-first': fiftyFirstBattleMapUrl,
'battle-map-fifty-second': fiftySecondBattleMapUrl
};

View File

@@ -7,6 +7,10 @@ import {
fiftyFirstBattleMap,
fiftyFirstBattleUnits,
fiftyFirstBattleVictoryPages,
fiftySecondBattleBonds,
fiftySecondBattleMap,
fiftySecondBattleUnits,
fiftySecondBattleVictoryPages,
firstBattleBonds,
fifteenthBattleBonds,
fifteenthBattleMap,
@@ -260,7 +264,8 @@ export type BattleScenarioId =
| 'forty-eighth-battle-meng-huo-main-force'
| 'forty-ninth-battle-meng-huo-second-capture'
| 'fiftieth-battle-meng-huo-third-capture'
| 'fifty-first-battle-meng-huo-fourth-capture';
| 'fifty-first-battle-meng-huo-fourth-capture'
| 'fifty-second-battle-meng-huo-fifth-capture';
export type BattleObjectiveKind = 'defeat-leader' | 'pacify-leader' | 'keep-unit-alive' | 'secure-terrain' | 'quick-victory';
@@ -3319,6 +3324,73 @@ export const fiftyFirstBattleScenario: BattleScenarioDefinition = {
nextCampScene: 'CampScene'
};
export const fiftySecondBattleScenario: BattleScenarioDefinition = {
id: 'fifty-second-battle-meng-huo-fifth-capture',
title: '칠종칠금 5차전',
victoryConditionLabel: '맹획 다섯 번째 생포와 강경파 분리',
defeatConditionLabel: '제갈량 퇴각',
openingObjectiveLines: [
'강경파 호족이 회유 퇴로를 배신이라 부르며 길목을 막고 있습니다. 맹획을 다시 생포하되, 물러설 뜻이 있는 호족이 본대와 갈라질 길을 지켜야 합니다.',
'마을 보증과 포로장 장부가 흔들리면 지난 네 번의 회유도 약해집니다. 강경파 요새를 누르고, 마을과 포로장을 지켜 남중 안의 의심을 끊으십시오.',
'제갈량은 반드시 생존해야 합니다. 마량과 황권으로 말을 남기고, 왕평과 마대로 퇴로를 열며, 조운과 황충으로 추격선을 억제하십시오.'
],
map: fiftySecondBattleMap,
units: fiftySecondBattleUnits,
bonds: fiftySecondBattleBonds,
mapTextureKey: 'battle-map-fifty-second',
leaderUnitId: 'menghuo-fifth-leader',
quickVictoryTurnLimit: 98,
baseVictoryGold: 12940,
objectives: [
{
id: 'pacify-meng-huo-fifth',
kind: 'pacify-leader',
label: '맹획 다섯 번째 생포',
rewardGold: 8780,
unitId: 'menghuo-fifth-leader'
},
{
id: 'zhuge-liang',
kind: 'keep-unit-alive',
label: '제갈량 생존',
rewardGold: 2220,
unitId: 'zhuge-liang'
},
{
id: 'hardliner-separation',
kind: 'secure-terrain',
label: '강경파 분리로 확보',
rewardGold: 4380,
terrain: 'road'
},
{
id: 'clan-villages',
kind: 'secure-terrain',
label: '회유 마을 보호',
rewardGold: 4040,
terrain: 'village'
},
{
id: 'hardliner-forts',
kind: 'secure-terrain',
label: '강경파 요새 제압',
rewardGold: 3860,
terrain: 'fort'
},
{
id: 'quick',
kind: 'quick-victory',
label: '98턴 이내 다섯 번째 생포',
rewardGold: 2920,
maxTurn: 98
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 70', '상처약 54', '탁주 24', '강경파 분리 장부 1', '남중 회유 깃발 1'],
victoryPages: fiftySecondBattleVictoryPages,
nextCampScene: 'CampScene'
};
export const defaultBattleScenarioId: BattleScenarioId = firstBattleScenario.id;
export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition> = {
@@ -3372,7 +3444,8 @@ export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition>
'forty-eighth-battle-meng-huo-main-force': fortyEighthBattleScenario,
'forty-ninth-battle-meng-huo-second-capture': fortyNinthBattleScenario,
'fiftieth-battle-meng-huo-third-capture': fiftiethBattleScenario,
'fifty-first-battle-meng-huo-fourth-capture': fiftyFirstBattleScenario
'fifty-first-battle-meng-huo-fourth-capture': fiftyFirstBattleScenario,
'fifty-second-battle-meng-huo-fifth-capture': fiftySecondBattleScenario
};
export const defaultBattleScenario = battleScenarios[defaultBattleScenarioId];

View File

@@ -6,6 +6,7 @@ import {
eleventhBattleScenario,
fiftiethBattleScenario,
fiftyFirstBattleScenario,
fiftySecondBattleScenario,
fortiethBattleScenario,
fortyFirstBattleScenario,
fortySecondBattleScenario,
@@ -65,6 +66,8 @@ import {
fiftiethBattleVictoryPages,
fiftyFirstBattleIntroPages,
fiftyFirstBattleVictoryPages,
fiftySecondBattleIntroPages,
fiftySecondBattleVictoryPages,
fortiethBattleIntroPages,
fortiethBattleVictoryPages,
fortyFirstBattleIntroPages,
@@ -745,13 +748,24 @@ const sortieFlows: Record<string, SortieFlow> = {
},
[fiftyFirstBattleScenario.id]: {
afterBattleId: fiftyFirstBattleScenario.id,
eyebrow: '다음 장 준비',
title: '더 깊은 남중 회유',
eyebrow: '다음 장',
title: fiftySecondBattleScenario.title,
description:
'맹획은 네 번째로 붙잡혔고, 회유 퇴로와 보증 장부는 남중 호족들의 말 속에 남았습니다. 다음 장에서는 더 깊은 산채와 강경파 호족을 상대로 같은 약속을 지킬 수 있는지 다룹니다.',
rewardHint: '다음 장: 칠종칠금 5차전과 남중 강경파 회유 준비 중',
pages: fiftyFirstBattleVictoryPages,
unavailableNotice: '칠종칠금 5차전은 다음 작업에서 이어집니다. 지금은 네 번째 생포 뒤의 보증 장부, 퇴로 표식, 강경파 분리 흐름을 정비할 수 있습니다.'
'맹획은 네 번째로 붙잡혔고, 회유 퇴로와 보증 장부는 남중 호족들의 말 속에 남았습니다. 이제 강경파 호족이 그 길을 끊으려 하니, 다섯 번째 생포에서는 회유를 받아들일 자와 끝까지 싸울 자를 전장 안에서 분리해야 합니다.',
rewardHint: `예상 보상: ${fiftySecondBattleScenario.title} 개방 / 강경파 분리 장부`,
nextBattleId: fiftySecondBattleScenario.id,
campaignStep: 'fifty-second-battle',
pages: [...fiftyFirstBattleVictoryPages, ...fiftySecondBattleIntroPages]
},
[fiftySecondBattleScenario.id]: {
afterBattleId: fiftySecondBattleScenario.id,
eyebrow: '다음 장 준비',
title: '여섯 번째 회유의 길',
description:
'맹획은 다섯 번째로 붙잡혔고, 강경파 호족과 물러선 호족의 말이 갈라졌습니다. 다음 장에서는 남중의 자존심을 더 직접적으로 마주하면서도, 지난 회유의 약속을 무너뜨리지 않는 길을 준비합니다.',
rewardHint: '다음 장: 칠종칠금 6차전과 마지막 설득 준비 중',
pages: fiftySecondBattleVictoryPages,
unavailableNotice: '칠종칠금 6차전은 다음 작업에서 이어집니다. 지금은 다섯 번째 생포 뒤의 강경파 분리 장부와 회유 깃발을 정비할 수 있습니다.'
}
};

View File

@@ -3350,6 +3350,59 @@ export const fiftyFirstBattleVictoryPages: StoryPage[] = [
}
];
export const fiftySecondBattleIntroPages: StoryPage[] = [
{
id: 'fifty-second-hardliner-split',
bgm: 'story-dark',
chapter: '강경파의 갈라짐',
background: 'story-militia',
speaker: '마량',
text: '네 번째 회유 뒤 일부 호족은 맹획의 깃발 아래 남아 있으면서도 마을을 지키는 길을 찾고 있습니다. 반대로 강경파는 그 길을 배신이라 부르며 퇴로를 끊으려 합니다.'
},
{
id: 'fifty-second-fifth-capture-plan',
bgm: 'battle-prep',
chapter: '다섯 번째 생포',
background: 'story-three-heroes',
speaker: '제갈량',
text: '이번 전투는 맹획을 다시 잡는 것만으로는 부족합니다. 강경파 호족을 본대와 분리하고, 회유 길목과 마을 보증을 동시에 지키면 남중 안에서 싸움을 그만둘 명분이 더 커질 것입니다.'
},
{
id: 'fifty-second-sortie',
bgm: 'battle-prep',
chapter: '칠종칠금 5차전',
background: 'story-sortie',
speaker: '왕평',
text: '깊은 죽림과 협곡이 이어져 있습니다. 장수마다 맡을 길이 다릅니다. 마량과 황권은 말을 남기고, 왕평과 마대는 물러날 길을 열며, 조운과 황충은 추격을 막아야 합니다.'
}
];
export const fiftySecondBattleVictoryPages: StoryPage[] = [
{
id: 'fifty-second-victory-fifth-capture',
bgm: 'militia-theme',
chapter: '다섯 번째 생포',
background: 'story-sortie',
text: '맹획은 다섯 번째로 포위되었고, 강경파 호족은 본대와 갈라졌습니다. 촉한군은 다시 마을과 퇴로를 지켰고, 돌아간 자들은 이제 맹획의 말만 듣지 않게 되었습니다.'
},
{
id: 'fifty-second-victory-hardliner-ledger',
bgm: 'story-dark',
chapter: '갈라진 장부',
background: 'story-militia',
speaker: '황권',
text: '끝까지 싸운 자와 물러난 자의 이름이 더 분명해졌습니다. 처벌의 장부가 아니라 약속의 장부로 남겨야 합니다. 그래야 다음 석방도 군율을 잃지 않습니다.'
},
{
id: 'fifty-second-next-sixth-capture',
bgm: 'story-dark',
chapter: '여섯 번째 길',
background: 'story-three-heroes',
speaker: '제갈량',
text: '남중의 마음은 점점 흔들리고 있습니다. 그러나 맹획의 자존심은 아직 마지막 벽처럼 남아 있습니다. 다음 싸움에서는 그 자존심을 꺾되, 남중 전체를 꺾지는 말아야 합니다.'
}
];
export const firstBattleMap: BattleMap = {
width: 20,
height: 18,
@@ -3801,6 +3854,12 @@ export const fiftyFirstBattleMap: BattleMap = {
terrain: createFiftyFirstBattleTerrain()
};
export const fiftySecondBattleMap: BattleMap = {
width: 104,
height: 86,
terrain: createFiftySecondBattleTerrain()
};
export const firstBattleUnits: UnitData[] = [
{
id: 'liu-bei',
@@ -16187,6 +16246,94 @@ export const fiftyFirstBattleUnits: UnitData[] = [
createThirtyFirstEnemyUnit('menghuo-fourth-leader', '맹획', '남만왕', 'rebelLeader', 156, 1048, 258, 96, 43)
];
const fiftySecondBattleAllyPositions: Record<string, { x: number; y: number }> = {
'guan-yu': { x: 15, y: 65 },
'zhang-fei': { x: 20, y: 67 },
'jian-yong': { x: 11, y: 72 },
'mi-zhu': { x: 13, y: 70 },
'sun-qian': { x: 17, y: 74 },
'zhao-yun': { x: 25, y: 62 },
'zhuge-liang': { x: 14, y: 62 },
'ma-liang': { x: 18, y: 59 },
'yi-ji': { x: 11, y: 77 },
'gong-zhi': { x: 21, y: 75 },
'huang-zhong': { x: 28, y: 63 },
'wei-yan': { x: 33, y: 67 },
'pang-tong': { x: 16, y: 56 },
'fa-zheng': { x: 22, y: 57 },
'wu-yi': { x: 35, y: 72 },
'yan-yan': { x: 38, y: 65 },
'li-yan': { x: 27, y: 55 },
'huang-quan': { x: 11, y: 60 },
'ma-chao': { x: 40, y: 62 },
'ma-dai': { x: 43, y: 67 },
'wang-ping': { x: 30, y: 58 }
};
export const fiftySecondBattleUnits: 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, fiftySecondBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })),
createThirtyFirstEnemyUnit('menghuo-fifth-scout-a', '강경파 정찰병', '서쪽 죽림 정찰', 'bandit', 154, 684, 206, 47, 38),
createThirtyFirstEnemyUnit('menghuo-fifth-scout-b', '강경파 정찰병', '늪지 정찰', 'bandit', 154, 684, 206, 63, 36),
createThirtyFirstEnemyUnit('menghuo-fifth-scout-c', '강경파 정찰병', '마을 감시', 'bandit', 155, 692, 208, 78, 53),
createThirtyFirstEnemyUnit('menghuo-fifth-scout-d', '강경파 정찰병', '동쪽 협곡 감시', 'bandit', 155, 692, 208, 94, 68),
createThirtyFirstEnemyUnit('menghuo-fifth-scout-e', '강경파 정찰병', '북쪽 산길 감시', 'bandit', 156, 700, 210, 55, 26),
createThirtyFirstEnemyUnit('menghuo-fifth-scout-f', '강경파 정찰병', '분리로 감시', 'bandit', 156, 700, 210, 70, 74),
createThirtyFirstEnemyUnit('menghuo-fifth-vine-a', '강경파 등갑병', '죽림 등갑병', 'yellowTurban', 155, 960, 244, 52, 47),
createThirtyFirstEnemyUnit('menghuo-fifth-vine-b', '강경파 등갑병', '불씨 등갑병', 'yellowTurban', 156, 972, 246, 65, 50),
createThirtyFirstEnemyUnit('menghuo-fifth-vine-c', '강경파 등갑병', '마을 등갑병', 'yellowTurban', 156, 972, 246, 78, 60),
createThirtyFirstEnemyUnit('menghuo-fifth-vine-d', '강경파 등갑병', '본영 등갑병', 'yellowTurban', 157, 984, 248, 90, 52),
createThirtyFirstEnemyUnit('menghuo-fifth-vine-e', '강경파 등갑병', '후위 등갑병', 'yellowTurban', 157, 984, 248, 98, 44),
createThirtyFirstEnemyUnit('menghuo-fifth-vine-f', '강경파 등갑병', '협곡 등갑병', 'yellowTurban', 158, 996, 250, 86, 33),
createThirtyFirstEnemyUnit('menghuo-fifth-archer-a', '남만 죽림 궁병', '독천 궁병', 'archer', 154, 736, 218, 48, 30),
createThirtyFirstEnemyUnit('menghuo-fifth-archer-b', '남만 죽림 궁병', '절벽 궁병', 'archer', 155, 744, 220, 64, 28),
createThirtyFirstEnemyUnit('menghuo-fifth-archer-c', '남만 죽림 궁병', '마을 궁병', 'archer', 155, 744, 220, 76, 46),
createThirtyFirstEnemyUnit('menghuo-fifth-archer-d', '남만 죽림 궁병', '늪지 궁병', 'archer', 156, 752, 222, 88, 64),
createThirtyFirstEnemyUnit('menghuo-fifth-archer-e', '남만 죽림 궁병', '본영 궁병', 'archer', 156, 752, 222, 97, 57),
createThirtyFirstEnemyUnit('menghuo-fifth-beast-a', '남만 맹수 추격대', '강가 맹수대', 'cavalry', 156, 976, 248, 58, 40),
createThirtyFirstEnemyUnit('menghuo-fifth-beast-b', '남만 맹수 추격대', '늪지 맹수대', 'cavalry', 156, 976, 248, 71, 42),
createThirtyFirstEnemyUnit('menghuo-fifth-beast-c', '남만 맹수 추격대', '산채 맹수대', 'cavalry', 157, 988, 250, 83, 55),
createThirtyFirstEnemyUnit('menghuo-fifth-beast-d', '남만 맹수 추격대', '추격 맹수대', 'cavalry', 157, 988, 250, 95, 61),
createThirtyFirstEnemyUnit('menghuo-fifth-beast-e', '남만 맹수 추격대', '분리로 차단대', 'cavalry', 158, 1000, 252, 69, 70),
createThirtyFirstEnemyUnit('menghuo-fifth-ambusher-a', '강경파 매복병', '죽림 매복병', 'bandit', 155, 704, 212, 39, 53),
createThirtyFirstEnemyUnit('menghuo-fifth-ambusher-b', '강경파 매복병', '숲속 매복병', 'bandit', 156, 712, 214, 55, 56),
createThirtyFirstEnemyUnit('menghuo-fifth-ambusher-c', '강경파 매복병', '강가 매복병', 'bandit', 156, 712, 214, 68, 69),
createThirtyFirstEnemyUnit('menghuo-fifth-ambusher-d', '강경파 매복병', '후방 차단대', 'bandit', 157, 720, 216, 88, 76),
createThirtyFirstEnemyUnit('menghuo-fifth-ambusher-e', '강경파 매복병', '서쪽 차단대', 'bandit', 157, 720, 216, 34, 66),
createThirtyFirstEnemyUnit('menghuo-fifth-ambusher-f', '강경파 매복병', '분리로 감시대', 'bandit', 158, 728, 218, 75, 74),
createThirtyFirstEnemyUnit('menghuo-fifth-guard-a', '맹획 오차 친위', '포로장 친위대', 'yellowTurban', 158, 1012, 254, 72, 44),
createThirtyFirstEnemyUnit('menghuo-fifth-guard-b', '맹획 오차 친위', '산채 친위대', 'yellowTurban', 158, 1012, 254, 85, 50),
createThirtyFirstEnemyUnit('menghuo-fifth-guard-c', '맹획 오차 친위', '본영 친위대', 'yellowTurban', 159, 1024, 256, 96, 47),
createThirtyFirstEnemyUnit('menghuo-fifth-guard-d', '맹획 오차 친위', '죽림 친위대', 'yellowTurban', 159, 1024, 256, 91, 37),
createThirtyFirstEnemyUnit('menghuo-fifth-shaman-a', '독천 제사장', '늪지 제사장', 'strategist', 157, 784, 230, 64, 38),
createThirtyFirstEnemyUnit('menghuo-fifth-shaman-b', '독천 제사장', '강가 제사장', 'strategist', 158, 792, 232, 79, 51),
createThirtyFirstEnemyUnit('menghuo-fifth-shaman-c', '독천 제사장', '산채 제사장', 'strategist', 158, 792, 232, 90, 40),
createThirtyFirstEnemyUnit('menghuo-fifth-shaman-d', '독천 제사장', '죽림 제사장', 'strategist', 159, 800, 234, 84, 59),
createThirtyFirstEnemyUnit('menghuo-fifth-officer-zhurong', '축융 부인', '남중 화전장', 'rebelLeader', 160, 1058, 264, 82, 67),
createThirtyFirstEnemyUnit('menghuo-fifth-officer-mulu', '목록대왕', '맹수대왕', 'rebelLeader', 160, 1058, 264, 88, 39),
createThirtyFirstEnemyUnit('menghuo-fifth-officer-duosi', '타사대왕', '독천 호족장', 'rebelLeader', 159, 1038, 258, 72, 62),
createThirtyFirstEnemyUnit('menghuo-fifth-officer-mengyou', '맹우', '맹획의 아우', 'rebelLeader', 159, 1038, 258, 68, 54),
createThirtyFirstEnemyUnit('menghuo-fifth-leader', '맹획', '남만왕', 'rebelLeader', 162, 1100, 270, 98, 45)
];
export const firstBattleBonds: BattleBond[] = [
{
id: 'liu-bei__guan-yu',
@@ -17151,6 +17298,35 @@ export const mengHuoFourthCaptureBonds: BattleBond[] = [
export const fiftyFirstBattleBonds: BattleBond[] = [...fiftiethBattleBonds, ...mengHuoFourthCaptureBonds].map(
cloneBattleBondForScenario
);
export const mengHuoFifthCaptureBonds: BattleBond[] = [
{
id: 'zhuge-liang__huang-quan_fifth-capture',
unitIds: ['zhuge-liang', 'huang-quan'],
title: '강경파 분리 장부',
level: 53,
exp: 0,
description: '제갈량의 회유 방침과 황권의 장부는 끝까지 싸운 자와 물러난 자를 갈라, 불필요한 원한을 줄인다.'
},
{
id: 'ma-liang__wang-ping_fifth-capture',
unitIds: ['ma-liang', 'wang-ping'],
title: '말과 길의 분리',
level: 49,
exp: 0,
description: '마량이 호족에게 남길 말을 고르고 왕평이 열린 길을 지켜, 전장 안에서도 항복의 길을 보존한다.'
},
{
id: 'zhao-yun__huang-zhong_fifth-capture',
unitIds: ['zhao-yun', 'huang-zhong'],
title: '추격선 억제',
level: 45,
exp: 0,
description: '조운과 황충은 맹수대와 고지 궁병을 눌러, 강경파가 회유 길목을 짓밟지 못하게 한다.'
}
];
export const fiftySecondBattleBonds: BattleBond[] = [...fiftyFirstBattleBonds, ...mengHuoFifthCaptureBonds].map(
cloneBattleBondForScenario
);
function createEighthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 22 }, (_, y) =>
@@ -19792,6 +19968,79 @@ function createFiftyFirstBattleTerrain(): TerrainType[][] {
);
}
function createFiftySecondBattleTerrain(): TerrainType[][] {
return Array.from({ length: 86 }, (_, y) =>
Array.from({ length: 104 }, (_, x): TerrainType => {
if (
(x >= 0 && x <= 103 && y >= 78) ||
(x >= 65 && x <= 71 && y >= 0 && y <= 80) ||
(x >= 5 && x <= 31 && y >= 69 && y <= 85) ||
(x >= 78 && x <= 95 && y >= 60 && y <= 78)
) {
return 'river';
}
if (
(x >= 10 && x <= 98 && y >= 65 && y <= 71) ||
(x >= 28 && x <= 76 && y >= 44 && y <= 51) ||
(x >= 72 && x <= 98 && y >= 36 && y <= 42) ||
(x >= 39 && x <= 47 && y >= 41 && y <= 74) ||
(x >= 78 && x <= 84 && y >= 50 && y <= 82) ||
(x >= 18 && x <= 52 && y >= 57 && y <= 61)
) {
return 'road';
}
if (
(x >= 18 && x <= 74 && y >= 21 && y <= 76) ||
(x >= 56 && x <= 98 && y >= 29 && y <= 72) ||
(x >= 2 && x <= 39 && y >= 51 && y <= 76) ||
(x >= 80 && x <= 103 && y >= 43 && y <= 75)
) {
return 'forest';
}
if (
(x >= 0 && x <= 32 && y <= 40) ||
(x >= 34 && x <= 70 && y <= 30) ||
(x >= 73 && x <= 103 && y <= 39) ||
(x >= 88 && x <= 103 && y >= 35 && y <= 57)
) {
return 'hill';
}
if (
(x <= 2 && y <= 76) ||
(x >= 101 && y <= 72) ||
(x >= 31 && x <= 37 && y >= 0 && y <= 42) ||
(x >= 70 && x <= 76 && y >= 0 && y <= 36) ||
(x >= 44 && x <= 50 && y >= 66 && y <= 85)
) {
return 'cliff';
}
if (
(x >= 11 && x <= 26 && y >= 61 && y <= 73) ||
(x >= 40 && x <= 56 && y >= 45 && y <= 58) ||
(x >= 77 && x <= 93 && y >= 51 && y <= 63) ||
(x >= 82 && x <= 96 && y >= 34 && y <= 46)
) {
return 'village';
}
if (
(x >= 24 && x <= 38 && y >= 53 && y <= 64) ||
(x >= 65 && x <= 80 && y >= 58 && y <= 70) ||
(x >= 83 && x <= 97 && y >= 41 && y <= 53)
) {
return 'camp';
}
if (
(x >= 48 && x <= 65 && y >= 33 && y <= 44) ||
(x >= 74 && x <= 94 && y >= 33 && y <= 47) ||
(x >= 86 && x <= 98 && y >= 45 && y <= 56)
) {
return 'fort';
}
return 'plain';
})
);
}
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
return {
...cloneUnitForScenario(unit),