export class JobSystem { constructor(game) { this.game = game; this.jobs = []; this.activeJob = null; this.jobTimer = 0; this.completedToday = 0; this.lastDay = 0; } init() { this.generateJobs(); } generateJobs() { const allJobs = [ { id: 'wash_car', name: 'Помыть машину', pay: 40, duration: 15, desc: 'Помыть машину на парковке', location: 'parking', skill: 'trading' }, { id: 'unload', name: 'Разгрузить товар', pay: 80, duration: 25, desc: 'Разгрузить товар у магазина', location: 'shop', skill: 'survival' }, { id: 'flyers', name: 'Раздать листовки', pay: 30, duration: 12, desc: 'Раздавать листовки на дороге', location: 'road', skill: 'begging' }, { id: 'sweep', name: 'Подмести двор', pay: 25, duration: 10, desc: 'Навести порядок у церкви', location: 'church', skill: 'survival' }, { id: 'help_granny', name: 'Помочь с сумками', pay: 35, duration: 15, desc: 'Донести сумки в парк', location: 'park', skill: 'survival' }, { id: 'collect_trash', name: 'Собрать мусор', pay: 20, duration: 8, desc: 'Собрать мусор в парке', location: 'park', skill: 'scavenging' }, { id: 'guard_stuff', name: 'Посторожить багаж', pay: 45, duration: 20, desc: 'Посторожить вещи на остановке', location: 'busstop', skill: 'survival' }, ]; // Выбираем 3 случайных const shuffled = allJobs.sort(() => Math.random() - 0.5); this.jobs = shuffled.slice(0, 3).map(j => ({ ...j, available: true })); } getLocationPosition(loc) { const positions = { parking: { x: 40, z: -55 }, shop: { x: 20, z: -20 }, road: { x: 0, z: 0 }, church: { x: 70, z: 50 }, park: { x: -30, z: 40 }, busstop: { x: -38, z: -10 }, }; return positions[loc] || { x: 0, z: 0 }; } getLocationName(loc) { const names = { parking: 'парковке', shop: 'магазину', road: 'дороге', church: 'церкви', park: 'парку', busstop: 'остановке', }; return names[loc] || 'месту'; } showJobBoard() { if (this.activeJob) { this.game.notify('Вы уже выполняете работу!'); return; } const availableJobs = this.jobs.filter(j => j.available); if (availableJobs.length === 0) { this.game.ui.showDialog('Доска объявлений', 'Сейчас нет доступных подработок. Загляните завтра.', [ 'Ладно' ], () => this.game.ui.hideDialog()); return; } const payMod = this.game.reputation.getJobPayModifier(); const choices = availableJobs.map(j => { const pay = Math.floor(j.pay * payMod); return `${j.name} — ${pay}₽ (${j.desc})`; }); choices.push('Уйти'); this.game.sound.playDialogOpen(); this.game.ui.showDialog('Доска объявлений', 'Доступные подработки:', choices, (index) => { if (index < availableJobs.length) { this.startJob(availableJobs[index]); } this.game.ui.hideDialog(); }); } startJob(job) { this.activeJob = { ...job }; this.jobTimer = 0; this.activeJob.isWorking = false; this.activeJob.targetPos = this.getLocationPosition(job.location); const locName = this.getLocationName(job.location); this.game.notify(`Работа принята: ${job.name}. Идите к ${locName}!`); } update(dt) { // Обновляем список работ при новом дне if (this.game.gameDay !== this.lastDay) { this.lastDay = this.game.gameDay; this.completedToday = 0; this.generateJobs(); } if (!this.activeJob) return; const player = this.game.player; const pos = this.activeJob.targetPos; const dx = player.position.x - pos.x; const dz = player.position.z - pos.z; const dist = Math.sqrt(dx * dx + dz * dz); if (dist < 10) { if (!this.activeJob.isWorking) { this.activeJob.isWorking = true; this.game.notify('Вы на месте. Работаете... (оставайтесь рядом)'); } this.jobTimer += dt; const progress = Math.min(1, this.jobTimer / this.activeJob.duration); this.game.ui.updateJobProgress(progress, this.activeJob.name); if (this.jobTimer >= this.activeJob.duration) { this.completeJob(); } } else if (this.activeJob.isWorking) { this.activeJob.isWorking = false; this.game.notify('Вы ушли с рабочего места! Вернитесь!', 'bad'); } } completeJob() { const payMod = this.game.reputation.getJobPayModifier(); const pay = Math.floor(this.activeJob.pay * payMod); this.game.player.stats.money += pay; this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 8); this.game.sound.playCoin(); this.game.reputation.change(3); this.game.skills.addXP(this.activeJob.skill || 'survival', 3); this.game.notify(`Работа выполнена! +${pay}₽, +8 Настроение`, 'good'); this.game.questSystem.onEvent('complete_job'); this.game.totalJobsCompleted++; // Ачивки this.game.achievements.check('first_job_done'); if (this.game.totalJobsCompleted >= 10) { this.game.achievements.check('jobs_10'); } const idx = this.jobs.findIndex(j => j.id === this.activeJob.id); if (idx >= 0) this.jobs[idx].available = false; this.activeJob = null; this.jobTimer = 0; this.completedToday++; this.game.ui.hideJobProgress(); } cancelJob() { if (this.activeJob) { this.game.notify('Работа отменена.', 'bad'); this.game.reputation.change(-2); this.activeJob = null; this.jobTimer = 0; this.game.ui.hideJobProgress(); } } getSaveData() { return { completedToday: this.completedToday, lastDay: this.lastDay }; } loadSaveData(data) { if (data) { this.completedToday = data.completedToday || 0; this.lastDay = data.lastDay || 0; } } reset() { this.activeJob = null; this.jobTimer = 0; this.completedToday = 0; this.lastDay = 0; this.generateJobs(); } }