36 lines
3.1 KiB
JavaScript
36 lines
3.1 KiB
JavaScript
const { genPassword, pick } = require('../rng');
|
||
|
||
function generate(ctx) {
|
||
const { r, add, addPuzzle, motiveEvs, victim, killer, herring, district } = ctx;
|
||
const motiveId = 'Шантаж';
|
||
const pw = genPassword(r, victim);
|
||
const pwPuzzle = addPuzzle({
|
||
id: 'pz_md5', kind: 'md5', hash: require('../rng').md5(pw.answer), answer: pw.answer, style: pw.style,
|
||
prompt: `Ноутбук жертви. Логін відкритий, пароль — ні. Хеш пароля (md5): ${require('../rng').md5(pw.answer)}.`,
|
||
hint: (pw.personal
|
||
? 'Схоже на «особистий» пароль — щось про власника, латиницею. Досьє в поміч: '
|
||
: 'Пароль не пов\'язаний із жертвою — лише перебір за словником (rockyou.txt). ') + pw.hint
|
||
});
|
||
const secret = pick(r, [
|
||
`у березні ${killer.name} ${ctx.g(killer, 'збив', 'збила')} пішохода на трасі й ${ctx.g(killer, 'поїхав', 'поїхала')}; бампер ремонтували «без записів»`,
|
||
`диплом, за яким ${killer.name} ${ctx.g(killer, 'отримав', 'отримала')} роботу (${killer.job}), — куплений`,
|
||
`${killer.name} роками ${ctx.g(killer, 'зливав', 'зливала')} касу на роботі повз облік`
|
||
]);
|
||
motiveEvs.push(add({
|
||
id: 'mot_laptop', side: 'field', at: { type: 'unit', unit: victim.home, slot: 'письмовий стіл' }, needsIdentity: true, puzzle: pwPuzzle,
|
||
title: 'Ноутбук жертви', tag: 'мотив',
|
||
detail: `Чернетки листів без підпису: «Я знаю, що ${secret}. 10 000 щомісяця — і ніхто не дізнається». Остання чернетка різкіша: «Ціна подвоюється».`,
|
||
gives: { pointsTo: killer.id, motive: true }
|
||
}));
|
||
motiveEvs.push(add({
|
||
id: 'mot_cash', side: 'analyst', at: { type: 'sys', sys: 'bank' }, q: { sys: 'bank', match: killer.name }, requires: ['mot_laptop'],
|
||
title: 'Готівкові зняття', tag: 'мотив',
|
||
detail: `Рахунок ${killer.name}: десяте число кожного місяця — зняття 10 000 готівкою, банкомат біля ${district.buildings.find(b => b.id === 'shop').name}. Півроку поспіль. Останній місяць — 20 000.`,
|
||
gives: { pointsTo: killer.id, motive: true }
|
||
}));
|
||
const recapWhy = `Жертва знала чужу таємницю і брала за мовчання гроші. Таємниця така: ${secret}. Подвоєна «ціна мовчання» стала вироком самому шантажисту.`;
|
||
const herringLead = `Серед чернеток є і другий адресат: «Я знаю про ваші оборудки», — а хто в районі має «оборудки», всі скажуть одразу: ${herring.name}.`;
|
||
return { motiveId, recapWhy, herringLead };
|
||
}
|
||
|
||
module.exports = { generate };
|