48 lines
4.2 KiB
JavaScript
48 lines
4.2 KiB
JavaScript
|
|
const { caesar, ri } = require('../rng');
|
|||
|
|
|
|||
|
|
function generate(ctx) {
|
|||
|
|
const { r, add, addPuzzle, motiveEvs, victim, killer, herring, startingFacts, lair } = ctx;
|
|||
|
|
const motiveId = 'Борг';
|
|||
|
|
const rep = ctx.witnessFrom(ctx.citizens.filter(c => c.home !== victim.home));
|
|||
|
|
const shiftK = ri(r, 3, 9);
|
|||
|
|
const plainK = `Винен ${killer.last} ${killer.first[0]}. — дев'яносто тисяч. Прострочено двічі. Каже: відпрацюєш.`;
|
|||
|
|
const czK = addPuzzle({
|
|||
|
|
id: 'pz_caesar', kind: 'caesar', prompt: 'Нотатки зниклої особи — суцільний беззмістовний набір літер.',
|
|||
|
|
payload: caesar(plainK, shiftK), answer: plainK, shift: shiftK, hint: 'Схоже на шифр зсуву (Цезар): переберіть усі зсуви абетки.'
|
|||
|
|
});
|
|||
|
|
startingFacts.push(add({
|
|||
|
|
id: 'sf_report', side: 'field', at: { type: 'start' },
|
|||
|
|
title: 'Заява про зникнення', tag: 'жертва',
|
|||
|
|
detail: `${rep.name} ${ctx.g(rep, 'заявив', 'заявила')}: ${victim.name} ${ctx.g(victim, 'зник', 'зникла')} по дорозі додому. «За день до того ${ctx.g(victim, 'він просив', 'вона просила')} у мене грошей — багато і терміново. Сказали тільки: „інакше буде зле".»`,
|
|||
|
|
gives: { identity: true }
|
|||
|
|
}));
|
|||
|
|
motiveEvs.push(add({
|
|||
|
|
id: 'mot_iou', side: 'field', at: { type: 'unit', unit: victim.home, slot: 'письмовий стіл' }, puzzle: czK,
|
|||
|
|
title: 'Шифровані нотатки боржника', tag: 'мотив',
|
|||
|
|
detail: 'У шухляді — розписка на 90 000 без імені кредитора і нотатник, писаний шифром. Людина боялась навіть власних записів. Розшифруйте — і кредитор матиме ім\'я.',
|
|||
|
|
gives: { pointsTo: killer.id, motive: true }
|
|||
|
|
}));
|
|||
|
|
motiveEvs.push(add({
|
|||
|
|
id: 'mot_bank_k', side: 'analyst', at: { type: 'sys', sys: 'bank' }, q: { sys: 'bank', match: victim.name },
|
|||
|
|
title: 'Виписка зниклої особи', tag: 'мотив',
|
|||
|
|
detail: `Щомісячні перекази з рахунку жертви (отримувач: ${killer.name}) припинились три місяці тому. Останній коментар до переказу: «решту віддам, чесно».`,
|
|||
|
|
gives: { pointsTo: killer.id, motive: true }
|
|||
|
|
}));
|
|||
|
|
motiveEvs.push(add({
|
|||
|
|
id: 'mot_threat', side: 'field', at: { type: 'person', cid: ctx.witnessFrom(ctx.citizens.filter(c => ctx.unitBuilding(c.home) === ctx.unitBuilding(victim.home) && c.home !== victim.home)).id },
|
|||
|
|
title: 'Свідчення сусіда', tag: 'мотив',
|
|||
|
|
detail: `«Тиждень тому під дверима стояв хтось і цідив крізь зуби: „Тиждень. Або поїдеш зі мною і відпрацюєш". Я в чужі справи не лізу, але голос був недобрий.»`
|
|||
|
|
}));
|
|||
|
|
add({
|
|||
|
|
id: 'mot_lairclue', side: 'field', at: { type: 'unit', unit: killer.home, slot: 'під ліжком' },
|
|||
|
|
title: 'Ключ із биркою', tag: 'місце',
|
|||
|
|
detail: `Під ліжком — ящик з інструментами, а в ньому ключ від навісного замка зі свіжою паперовою биркою: «${lair.label}». Замок із комплекту — той самий, що зник із полиці маркету.`,
|
|||
|
|
gives: { lair: true }
|
|||
|
|
});
|
|||
|
|
const recapWhy = `Борг у 90 000, прострочений двічі. «Відпрацюєш» виявилось буквальним: ${killer.name} ${ctx.g(killer, 'вирішив', 'вирішила')} утримувати боржника, поки рідня не збере гроші.`;
|
|||
|
|
const herringLead = `«У зошитах жертви і ${herring.name} десь фігурує — теж, кажуть, позичали одне одному. Хто кому винен — спитайте самі.»`;
|
|||
|
|
return { motiveId, recapWhy, herringLead };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = { generate };
|