Add Red Cliffs fire attack chapter

This commit is contained in:
2026-06-23 07:15:43 +09:00
parent 7f80600d0c
commit 302f0e0a76
11 changed files with 1059 additions and 24 deletions

View File

@@ -43,6 +43,10 @@ import {
twentyFirstBattleMap,
twentyFirstBattleUnits,
twentyFirstBattleVictoryPages,
twentySecondBattleBonds,
twentySecondBattleMap,
twentySecondBattleUnits,
twentySecondBattleVictoryPages,
twentiethBattleBonds,
twentiethBattleMap,
twentiethBattleUnits,
@@ -110,7 +114,8 @@ export type BattleScenarioId =
| 'eighteenth-battle-bowang-ambush'
| 'nineteenth-battle-changban-refuge'
| 'twentieth-battle-jiangdong-envoy'
| 'twenty-first-battle-red-cliffs-vanguard';
| 'twenty-first-battle-red-cliffs-vanguard'
| 'twenty-second-battle-red-cliffs-fire';
export type BattleObjectiveKind = 'defeat-leader' | 'keep-unit-alive' | 'secure-terrain' | 'quick-victory';
@@ -1293,6 +1298,69 @@ export const twentyFirstBattleScenario: BattleScenarioDefinition = {
nextCampScene: 'CampScene'
};
export const twentySecondBattleScenario: BattleScenarioDefinition = {
id: 'twenty-second-battle-red-cliffs-fire',
title: '적벽 화공전',
victoryConditionLabel: '조조 본선 퇴각',
defeatConditionLabel: '유비 또는 제갈량 퇴각',
openingObjectiveLines: [
'황개의 거짓 항복선이 조조 함대로 향합니다. 조조군 감시선이 화선을 알아차리면 적벽의 불길은 시작되기도 전에 꺼집니다.',
'강 위에는 연환선과 배다리가 얽혀 있습니다. 전열 장수로 갑판 보병을 묶고, 기동 장수로 강안 기병을 끊어 화선 접안로를 열어야 합니다.',
'제갈량을 지키고 조조 본선을 퇴각시키십시오. 화선 준비 지점을 확보하면 적벽대전의 결정적 승리를 얻을 수 있습니다.'
],
map: twentySecondBattleMap,
units: twentySecondBattleUnits,
bonds: twentySecondBattleBonds,
mapTextureKey: 'battle-map-twenty-second',
leaderUnitId: 'redcliff-fire-leader-cao-cao',
quickVictoryTurnLimit: 31,
baseVictoryGold: 2840,
objectives: [
{
id: 'leader',
kind: 'defeat-leader',
label: '조조 본선 퇴각',
rewardGold: 1900,
unitId: 'redcliff-fire-leader-cao-cao'
},
{
id: 'liu-bei',
kind: 'keep-unit-alive',
label: '유비 생존',
rewardGold: 560,
unitId: 'liu-bei'
},
{
id: 'zhuge-liang',
kind: 'keep-unit-alive',
label: '제갈량 생존',
rewardGold: 860,
unitId: 'zhuge-liang'
},
{
id: 'fire-ship-landing',
kind: 'secure-terrain',
label: '화선 접안로 확보',
rewardGold: 980,
terrain: 'village'
},
{
id: 'quick',
kind: 'quick-victory',
label: '31턴 이내 승리',
rewardGold: 720,
maxTurn: 31
}
],
defeatConditions: [
{ kind: 'unit-defeated', unitId: 'liu-bei' },
{ kind: 'unit-defeated', unitId: 'zhuge-liang' }
],
itemRewards: ['콩 9', '상처약 6', '탁주 4', '화공 전과 +1', '동남풍 기록 +1'],
victoryPages: twentySecondBattleVictoryPages,
nextCampScene: 'CampScene'
};
export const defaultBattleScenarioId: BattleScenarioId = firstBattleScenario.id;
export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition> = {
@@ -1316,7 +1384,8 @@ export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition>
'eighteenth-battle-bowang-ambush': eighteenthBattleScenario,
'nineteenth-battle-changban-refuge': nineteenthBattleScenario,
'twentieth-battle-jiangdong-envoy': twentiethBattleScenario,
'twenty-first-battle-red-cliffs-vanguard': twentyFirstBattleScenario
'twenty-first-battle-red-cliffs-vanguard': twentyFirstBattleScenario,
'twenty-second-battle-red-cliffs-fire': twentySecondBattleScenario
};
export const defaultBattleScenario = battleScenarios[defaultBattleScenarioId];

View File

@@ -18,6 +18,7 @@ import {
tenthBattleScenario,
thirteenthBattleScenario,
twentyFirstBattleScenario,
twentySecondBattleScenario,
twentiethBattleScenario,
twelfthBattleScenario,
thirdBattleScenario,
@@ -59,6 +60,8 @@ import {
thirteenthBattleVictoryPages,
twentyFirstBattleIntroPages,
twentyFirstBattleVictoryPages,
twentySecondBattleIntroPages,
twentySecondBattleVictoryPages,
twentiethBattleIntroPages,
twentiethBattleVictoryPages,
twelfthBattleIntroPages,
@@ -291,13 +294,24 @@ const sortieFlows: Record<string, SortieFlow> = {
},
[twentyFirstBattleScenario.id]: {
afterBattleId: twentyFirstBattleScenario.id,
eyebrow: '다음 장 준비',
title: '적벽 화공 준비',
eyebrow: '다음 장',
title: twentySecondBattleScenario.title,
description:
'조조군 수군 선봉을 밀어내며 손유 동맹의 첫 전선이 세워졌습니다. 이제 주유와 황개, 제갈량의 계책이 맞물려 본격적인 화공을 준비해야 합니다.',
rewardHint: '다음 장: 황개 고육계와 적벽 화공 준비 중',
pages: twentyFirstBattleVictoryPages,
unavailableNotice: '황개 고육계와 적벽 화공 장은 다음 작업에서 이어집니다. 군영에서 화공 논의, 공명, 보급을 정비하십시오.'
rewardHint: `예상 보상: ${twentySecondBattleScenario.title} 개방 / 적벽대전 결전`,
nextBattleId: twentySecondBattleScenario.id,
campaignStep: 'twenty-second-battle',
pages: [...twentyFirstBattleVictoryPages, ...twentySecondBattleIntroPages]
},
[twentySecondBattleScenario.id]: {
afterBattleId: twentySecondBattleScenario.id,
eyebrow: '다음 장 준비',
title: '형주 확보 준비',
description:
'적벽의 불길로 조조의 남하가 꺾였습니다. 이제 유비군은 머물 땅을 마련하기 위해 형주 남부와 익주로 이어질 근거지를 준비해야 합니다.',
rewardHint: '다음 장: 형주 남부 확보 준비 중',
pages: twentySecondBattleVictoryPages,
unavailableNotice: '형주 남부 확보 장은 다음 작업에서 이어집니다. 군영에서 전후 수습, 공명, 보급을 정비하십시오.'
}
};

View File

@@ -1385,6 +1385,69 @@ export const twentyFirstBattleVictoryPages: StoryPage[] = [
}
];
export const twentySecondBattleIntroPages: StoryPage[] = [
{
id: 'twenty-second-huang-gai-bitter-plan',
bgm: 'story-dark',
chapter: '황개의 결단',
background: 'story-liu-bei',
speaker: '주유',
text: '황개 장군은 거짓 항복의 배를 준비했습니다. 조조가 그 배를 의심하지 않게 하려면, 유비군은 강안의 감시선을 흔들어 화선이 다가갈 길을 열어야 합니다.'
},
{
id: 'twenty-second-zhuge-wind-watch',
bgm: 'battle-prep',
chapter: '동남풍을 기다리다',
background: 'story-three-heroes',
speaker: '제갈량',
text: '바람은 아직 완전히 돌지 않았습니다. 그러나 때가 오면 불길은 강 위에서 산처럼 번질 것입니다. 그 전까지 조조의 척후와 갑판 궁병을 묶어 두어야 합니다.'
},
{
id: 'twenty-second-liu-bei-fire-line',
bgm: 'militia-theme',
chapter: '불길 앞의 뜻',
background: 'story-militia',
speaker: '유비',
portrait: 'liuBei',
text: '오늘의 불은 백성을 태우기 위한 불이 아니라 난세의 물결을 멈추기 위한 불이오. 화선이 닿을 때까지 강안 전선을 흔들림 없이 지킵시다.'
},
{
id: 'twenty-second-fire-attack-sortie',
bgm: 'battle-prep',
chapter: '적벽 화공전',
background: 'story-sortie',
speaker: '제갈량',
text: '조조의 함대가 사슬로 묶인 채 강북에 모였습니다. 화선의 길을 막는 초병을 베고, 조조 본선이 불길에 휩싸일 때까지 전선을 지키십시오.'
}
];
export const twentySecondBattleVictoryPages: StoryPage[] = [
{
id: 'twenty-second-victory-fire-rises',
bgm: 'battle-prep',
chapter: '불길이 일다',
background: 'story-sortie',
text: '화선이 조조군 함대에 닿자 강 위가 붉게 일렁였습니다. 사슬로 묶인 배들은 서로를 구하지 못했고, 장강의 바람은 불길을 북쪽으로 몰아붙였습니다.'
},
{
id: 'twenty-second-cao-cao-retreat',
bgm: 'story-dark',
chapter: '조조의 퇴각',
background: 'story-three-heroes',
speaker: '조조',
text: '오늘은 하늘과 강이 나를 막는구나. 그러나 난세는 아직 끝나지 않았다. 살아 돌아가 다시 군을 모으면, 이 치욕도 갚을 날이 있을 것이다.'
},
{
id: 'twenty-second-liu-bei-next-land',
bgm: 'militia-theme',
chapter: '형주를 바라보다',
background: 'story-militia',
speaker: '유비',
portrait: 'liuBei',
text: '조조의 대군은 물러났지만 우리의 근본은 아직 없습니다. 이제 백성이 머물 땅을 얻고, 형주와 익주로 향할 길을 차근히 세워야 합니다.'
}
];
export const firstBattleMap: BattleMap = {
width: 20,
height: 18,
@@ -1656,6 +1719,12 @@ export const twentyFirstBattleMap: BattleMap = {
terrain: createTwentyFirstBattleTerrain()
};
export const twentySecondBattleMap: BattleMap = {
width: 44,
height: 30,
terrain: createTwentySecondBattleTerrain()
};
export const firstBattleUnits: UnitData[] = [
{
id: 'liu-bei',
@@ -8132,6 +8201,405 @@ export const twentyFirstBattleUnits: UnitData[] = [
}
];
const twentySecondBattleAllyPositions: Record<string, { x: number; y: number }> = {
'liu-bei': { x: 4, y: 23 },
'guan-yu': { x: 6, y: 21 },
'zhang-fei': { x: 6, y: 25 },
'jian-yong': { x: 3, y: 26 },
'mi-zhu': { x: 5, y: 27 },
'sun-qian': { x: 8, y: 23 },
'zhao-yun': { x: 8, y: 20 },
'zhuge-liang': { x: 6, y: 22 }
};
export const twentySecondBattleUnits: UnitData[] = [
...[
...firstBattleUnits.filter((unit) => unit.faction === 'ally'),
...xuzhouRecruitUnits,
...caoBreakRecruitUnits,
...liuBiaoRecruitUnits,
...zhugeRecruitUnits
].map((unit) => placeScenarioUnit(unit, twentySecondBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })),
{
id: 'redcliff-fire-scout-a',
name: '조조 화선 감시병',
faction: 'enemy',
className: '강안 척후',
classKey: 'bandit',
level: 28,
exp: 42,
hp: 78,
maxHp: 78,
attack: 31,
move: 4,
stats: { might: 110, intelligence: 82, leadership: 88, agility: 108, luck: 74 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 4, exp: 4 },
armor: { itemId: 'rebel-vest', level: 3, exp: 42 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 14,
y: 21
},
{
id: 'redcliff-fire-scout-b',
name: '조조 화선 감시병',
faction: 'enemy',
className: '강변 척후',
classKey: 'bandit',
level: 28,
exp: 42,
hp: 78,
maxHp: 78,
attack: 31,
move: 4,
stats: { might: 110, intelligence: 82, leadership: 88, agility: 108, luck: 74 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 4, exp: 4 },
armor: { itemId: 'rebel-vest', level: 3, exp: 42 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 16,
y: 24
},
{
id: 'redcliff-fire-marine-a',
name: '조조 갑판 보병',
faction: 'enemy',
className: '갑판 보병',
classKey: 'yellowTurban',
level: 28,
exp: 44,
hp: 102,
maxHp: 102,
attack: 33,
move: 3,
stats: { might: 120, intelligence: 82, leadership: 102, agility: 90, luck: 74 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 12 },
armor: { itemId: 'lamellar-armor', level: 4, exp: 2 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 21,
y: 19
},
{
id: 'redcliff-fire-marine-b',
name: '조조 갑판 보병',
faction: 'enemy',
className: '갑판 보병',
classKey: 'yellowTurban',
level: 28,
exp: 44,
hp: 102,
maxHp: 102,
attack: 33,
move: 3,
stats: { might: 120, intelligence: 82, leadership: 102, agility: 90, luck: 74 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 12 },
armor: { itemId: 'lamellar-armor', level: 4, exp: 2 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 23,
y: 21
},
{
id: 'redcliff-fire-marine-c',
name: '조조 갑판 보병',
faction: 'enemy',
className: '연환선 보병',
classKey: 'yellowTurban',
level: 29,
exp: 46,
hp: 106,
maxHp: 106,
attack: 34,
move: 3,
stats: { might: 122, intelligence: 84, leadership: 104, agility: 92, luck: 75 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 18 },
armor: { itemId: 'reinforced-lamellar', level: 4, exp: 8 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 30,
y: 14
},
{
id: 'redcliff-fire-marine-d',
name: '조조 갑판 보병',
faction: 'enemy',
className: '연환선 보병',
classKey: 'yellowTurban',
level: 29,
exp: 46,
hp: 106,
maxHp: 106,
attack: 34,
move: 3,
stats: { might: 122, intelligence: 84, leadership: 104, agility: 92, luck: 75 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 18 },
armor: { itemId: 'reinforced-lamellar', level: 4, exp: 8 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 32,
y: 17
},
{
id: 'redcliff-fire-archer-a',
name: '조조 선상 궁병',
faction: 'enemy',
className: '선상 궁병',
classKey: 'archer',
level: 28,
exp: 42,
hp: 76,
maxHp: 76,
attack: 33,
move: 3,
stats: { might: 106, intelligence: 96, leadership: 92, agility: 104, luck: 76 },
equipment: {
weapon: { itemId: 'short-bow', level: 4, exp: 12 },
armor: { itemId: 'cloth-armor', level: 4, exp: 4 },
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
},
x: 22,
y: 15
},
{
id: 'redcliff-fire-archer-b',
name: '조조 선상 궁병',
faction: 'enemy',
className: '선상 궁병',
classKey: 'archer',
level: 28,
exp: 42,
hp: 76,
maxHp: 76,
attack: 33,
move: 3,
stats: { might: 106, intelligence: 96, leadership: 92, agility: 104, luck: 76 },
equipment: {
weapon: { itemId: 'short-bow', level: 4, exp: 12 },
armor: { itemId: 'cloth-armor', level: 4, exp: 4 },
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
},
x: 26,
y: 18
},
{
id: 'redcliff-fire-archer-c',
name: '조조 연환 궁병',
faction: 'enemy',
className: '연환선 궁병',
classKey: 'archer',
level: 29,
exp: 46,
hp: 78,
maxHp: 78,
attack: 34,
move: 3,
stats: { might: 108, intelligence: 98, leadership: 94, agility: 106, luck: 76 },
equipment: {
weapon: { itemId: 'short-bow', level: 4, exp: 20 },
armor: { itemId: 'cloth-armor', level: 4, exp: 8 },
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
},
x: 35,
y: 12
},
{
id: 'redcliff-fire-archer-d',
name: '조조 연환 궁병',
faction: 'enemy',
className: '연환선 궁병',
classKey: 'archer',
level: 29,
exp: 46,
hp: 78,
maxHp: 78,
attack: 34,
move: 3,
stats: { might: 108, intelligence: 98, leadership: 94, agility: 106, luck: 76 },
equipment: {
weapon: { itemId: 'short-bow', level: 4, exp: 20 },
armor: { itemId: 'cloth-armor', level: 4, exp: 8 },
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
},
x: 37,
y: 17
},
{
id: 'redcliff-fire-cavalry-a',
name: '조조 강안 기병',
faction: 'enemy',
className: '강안 기병',
classKey: 'cavalry',
level: 29,
exp: 46,
hp: 110,
maxHp: 110,
attack: 36,
move: 5,
stats: { might: 126, intelligence: 82, leadership: 100, agility: 118, luck: 76 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 22 },
armor: { itemId: 'lamellar-armor', level: 4, exp: 12 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 18,
y: 25
},
{
id: 'redcliff-fire-cavalry-b',
name: '조조 강안 기병',
faction: 'enemy',
className: '강안 기병',
classKey: 'cavalry',
level: 29,
exp: 46,
hp: 110,
maxHp: 110,
attack: 36,
move: 5,
stats: { might: 126, intelligence: 82, leadership: 100, agility: 118, luck: 76 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 22 },
armor: { itemId: 'lamellar-armor', level: 4, exp: 12 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 27,
y: 24
},
{
id: 'redcliff-fire-cavalry-c',
name: '조조 강안 기병',
faction: 'enemy',
className: '강북 기병',
classKey: 'cavalry',
level: 30,
exp: 48,
hp: 114,
maxHp: 114,
attack: 37,
move: 5,
stats: { might: 128, intelligence: 84, leadership: 102, agility: 120, luck: 77 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 28 },
armor: { itemId: 'reinforced-lamellar', level: 4, exp: 16 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 34,
y: 22
},
{
id: 'redcliff-fire-guard-a',
name: '조조 본선 친위',
faction: 'enemy',
className: '본선 친위',
classKey: 'yellowTurban',
level: 30,
exp: 50,
hp: 116,
maxHp: 116,
attack: 36,
move: 3,
stats: { might: 128, intelligence: 86, leadership: 110, agility: 94, luck: 78 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 34 },
armor: { itemId: 'reinforced-lamellar', level: 4, exp: 22 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 38,
y: 13
},
{
id: 'redcliff-fire-guard-b',
name: '조조 본선 친위',
faction: 'enemy',
className: '본선 친위',
classKey: 'yellowTurban',
level: 30,
exp: 50,
hp: 116,
maxHp: 116,
attack: 36,
move: 3,
stats: { might: 128, intelligence: 86, leadership: 110, agility: 94, luck: 78 },
equipment: {
weapon: { itemId: 'iron-spear', level: 4, exp: 34 },
armor: { itemId: 'reinforced-lamellar', level: 4, exp: 22 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 39,
y: 16
},
{
id: 'redcliff-fire-strategist-a',
name: '조조 수군 군리',
faction: 'enemy',
className: '연환선 군리',
classKey: 'archer',
level: 29,
exp: 48,
hp: 82,
maxHp: 82,
attack: 33,
move: 3,
stats: { might: 84, intelligence: 104, leadership: 98, agility: 90, luck: 78 },
equipment: {
weapon: { itemId: 'short-bow', level: 4, exp: 28 },
armor: { itemId: 'cloth-armor', level: 4, exp: 14 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 36,
y: 11
},
{
id: 'redcliff-fire-strategist-b',
name: '조조 수군 군리',
faction: 'enemy',
className: '연환선 군리',
classKey: 'archer',
level: 29,
exp: 48,
hp: 82,
maxHp: 82,
attack: 33,
move: 3,
stats: { might: 84, intelligence: 104, leadership: 98, agility: 90, luck: 78 },
equipment: {
weapon: { itemId: 'short-bow', level: 4, exp: 28 },
armor: { itemId: 'cloth-armor', level: 4, exp: 14 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 40,
y: 12
},
{
id: 'redcliff-fire-leader-cao-cao',
name: '조조',
faction: 'enemy',
className: '위왕군 총대장',
classKey: 'rebelLeader',
level: 32,
exp: 54,
hp: 156,
maxHp: 156,
attack: 39,
move: 4,
stats: { might: 130, intelligence: 118, leadership: 132, agility: 96, luck: 82 },
equipment: {
weapon: { itemId: 'leader-axe', level: 4, exp: 42 },
armor: { itemId: 'reinforced-lamellar', level: 4, exp: 34 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 41,
y: 14
}
];
export const firstBattleBonds: BattleBond[] = [
{
id: 'liu-bei__guan-yu',
@@ -8285,6 +8753,7 @@ export const eighteenthBattleBonds: BattleBond[] = [...sixteenthBattleBonds, ...
export const nineteenthBattleBonds: BattleBond[] = [...eighteenthBattleBonds].map(cloneBattleBondForScenario);
export const twentiethBattleBonds: BattleBond[] = [...nineteenthBattleBonds].map(cloneBattleBondForScenario);
export const twentyFirstBattleBonds: BattleBond[] = [...twentiethBattleBonds].map(cloneBattleBondForScenario);
export const twentySecondBattleBonds: BattleBond[] = [...twentyFirstBattleBonds].map(cloneBattleBondForScenario);
function createEighthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 22 }, (_, y) =>
@@ -8964,6 +9433,61 @@ function createTwentyFirstBattleTerrain(): TerrainType[][] {
);
}
function createTwentySecondBattleTerrain(): TerrainType[][] {
return Array.from({ length: 30 }, (_, y) =>
Array.from({ length: 44 }, (_, x): TerrainType => {
if ((x <= 4 && y >= 21 && y <= 28) || (x >= 5 && x <= 9 && y >= 24 && y <= 29)) {
return 'camp';
}
if ((x >= 36 && x <= 43 && y >= 10 && y <= 18) || (x >= 33 && x <= 37 && y >= 12 && y <= 16)) {
return 'fort';
}
if ((x >= 12 && x <= 15 && y >= 20 && y <= 22) || (x >= 27 && x <= 30 && y >= 11 && y <= 13)) {
return 'village';
}
if (
(y === 23 && x >= 3 && x <= 17) ||
(y === 20 && x >= 15 && x <= 28) ||
(y === 15 && x >= 28 && x <= 40) ||
(x === 36 && y >= 10 && y <= 22)
) {
return 'road';
}
if (
(x >= 7 && x <= 18 && y === 26 - Math.floor(x / 2)) ||
(x >= 19 && x <= 35 && y === 25 - Math.floor(x / 3)) ||
(x >= 30 && x <= 39 && y === 14)
) {
return 'road';
}
if ((x >= 18 && x <= 25 && y >= 0 && y <= 29) || (x >= 29 && x <= 31 && y >= 0 && y <= 22)) {
return 'river';
}
if ((x >= 14 && x <= 16 && y >= 24 && y <= 29) || (x >= 26 && x <= 28 && y >= 20 && y <= 29)) {
return 'river';
}
if (
(x >= 4 && x <= 13 && y >= 8 && y <= 17) ||
(x <= 8 && y <= 7) ||
(x >= 31 && x <= 42 && y <= 8)
) {
return 'forest';
}
if (
(x >= 9 && x <= 18 && y >= 2 && y <= 6) ||
(x >= 32 && x <= 43 && y >= 21 && y <= 29) ||
(x >= 38 && x <= 43 && y >= 3 && y <= 7)
) {
return 'hill';
}
if ((x <= 1 && y <= 13) || (x >= 42 && y <= 9) || (x >= 42 && y >= 20)) {
return 'cliff';
}
return 'plain';
})
);
}
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
return {
...cloneUnitForScenario(unit),