568 lines
23 KiB
JavaScript
568 lines
23 KiB
JavaScript
const { Telegraf, Scenes, session, Markup, Stage, Composer } = require('telegraf');
|
||
// Подключаем необходимые библиотеки
|
||
const { Op } = require('sequelize');
|
||
const sequelize = require('./db'); // Подключение базы данных
|
||
// Подключаем обработчики
|
||
const utils = require('./utils');
|
||
const handlers = require('./handlers');
|
||
const {
|
||
UserModel,
|
||
CharacterModel,
|
||
WorldModel,
|
||
JobModel,
|
||
PropertyModel,
|
||
AFKPropertyModel,
|
||
BusinessModel,
|
||
ReportModel,
|
||
BlockModel,
|
||
PromocodeModel,
|
||
EnterpriseModel,
|
||
WarehouseModel,
|
||
TruckModel,
|
||
SaleModel,
|
||
ResourcePriceModel,
|
||
SkillsModel,
|
||
DailyModel
|
||
} = global.config
|
||
const rpg = new Composer();
|
||
|
||
rpg.use(async (ctx, next) => {
|
||
let id = ctx.from.id
|
||
let username = ctx.from.username
|
||
if(username == null) username = ctx.from.id
|
||
switch(ctx.updateType){
|
||
case `message`:
|
||
console.log(utils.getCurrentTime() + `: ` + username + `: ` + ctx.update.message.text)
|
||
break;
|
||
case `callback_query`:
|
||
console.log(utils.getCurrentTime() + `: ${username}: ${ctx.update.callback_query.data}`)
|
||
break;
|
||
default:
|
||
console.log(ctx)
|
||
}
|
||
const start = Date.now()
|
||
const timeoutPromise = new Promise((resolve, reject) => {
|
||
|
||
setTimeout(() => {
|
||
reject(new Error('timeout'))
|
||
}, 1000 * 5)
|
||
})
|
||
|
||
const nextPromise = next()
|
||
.then(() => {
|
||
const ms = Date.now() - start
|
||
})
|
||
.catch((error) => {
|
||
handleError(error, ctx)
|
||
})
|
||
|
||
return Promise.race([timeoutPromise, nextPromise])
|
||
.catch((error) => {
|
||
if (error.message === 'timeout') {
|
||
console.error('timeout', ctx.update)
|
||
return false
|
||
}
|
||
|
||
return true
|
||
})
|
||
})
|
||
|
||
rpg.hears('RPG', async (ctx) => {
|
||
let message = `Меню:\n`;
|
||
const buttons = [];
|
||
buttons.push([{ text: 'Мой Персонаж', callback_data: 'rpg_profile' }]);
|
||
return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize());
|
||
});
|
||
|
||
rpg.action('rpg_profile', async (ctx) => {
|
||
const telegramId = ctx.from.id;
|
||
|
||
// Ищем персонажа
|
||
const character = await CharacterModel.findOne({ where: { telegram_id: telegramId } });
|
||
|
||
if (!character) {
|
||
return ctx.reply('Персонаж не найден. Создайте нового персонажа, чтобы начать игру!');
|
||
}
|
||
|
||
// Формируем профиль
|
||
const profile = `
|
||
🎭 Профиль персонажа:
|
||
👤 Имя: ${character.name || 'Не указано'}
|
||
🏆 Уровень: ${character.level} (${character.exp}/${character.level * 100} опыта)
|
||
❤️ Здоровье: ${character.hp}/${character.max_hp}
|
||
💪 Сила (F): ${character.force}
|
||
🧠 Интеллект (I): ${character.intelligence}
|
||
🛡️ Устойчивость (R): ${character.resilience}
|
||
🔋 Выносливость (E): ${character.endurance}
|
||
🔥 Стамина: ${character.stamina}/${character.max_stamina}
|
||
💰 Грязные деньги: ${character.dirtymoney}
|
||
🃏 Карточки: ${character.stealedcards}
|
||
🎒 Инвентарь (${character.inventory.length}/10): ${character.inventory.map((item) => item.name).join(', ') || 'Пусто'}
|
||
`;
|
||
|
||
// Отправляем сообщение
|
||
ctx.reply(profile.trim(), Markup.inlineKeyboard([
|
||
[Markup.button.callback('💼 Задачи', 'crime_missions')],
|
||
]));
|
||
});
|
||
|
||
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||
|
||
// Хранилище для отслеживания пользователей, которые уже прошли ввод
|
||
const usersCrimeNet = new Set();
|
||
const usersLocks = new Set();
|
||
|
||
rpg.hears('CampFireGG.Crime', async (ctx) => {
|
||
const userId = ctx.from.id;
|
||
if (!usersCrimeNet.has(userId) && userId != 275416286){
|
||
// Если пользователь вводит команду впервые
|
||
usersCrimeNet.add(userId);
|
||
const username = ctx.from.username || 'User';
|
||
const randomServer = `secure.net-${Math.floor(Math.random() * 99 + 1)}.campfiregg.crime`;
|
||
const sshCommand = `ssh ${username}@${randomServer}`;
|
||
|
||
// Сообщение для симуляции
|
||
const lines = [
|
||
`${sshCommand}`,
|
||
`> Connecting to secure servers with RSA key...`,
|
||
`> Authentication in progress...`,
|
||
`> User "${username}" identified.`,
|
||
`> Accessing CampFireGG.Crime...`,
|
||
`> Connection established. Welcome, ${username}.`,
|
||
];
|
||
|
||
// Отправляем первое сообщение
|
||
let sentMessage = await ctx.reply('> Initializing Crime.net...');
|
||
|
||
// Симуляция показа строки ssh блоками
|
||
let currentText = '';
|
||
let index = 0;
|
||
|
||
while (index < lines[0].length) {
|
||
const blockSize = Math.floor(Math.random() * 3) + 2; // Генерируем блок от 2 до 4 символов
|
||
currentText += lines[0].slice(index, index + blockSize); // Добавляем блок текста
|
||
index += blockSize; // Увеличиваем индекс
|
||
await ctx.telegram.editMessageText(sentMessage.chat.id, sentMessage.message_id, undefined, currentText);
|
||
await delay(100); // Задержка между блоками
|
||
}
|
||
|
||
// Последующие строки добавляются полностью, по одной
|
||
for (let i = 1; i < lines.length; i++) {
|
||
await delay(1500); // Задержка между строками
|
||
currentText += `\n${lines[i]}`;
|
||
await ctx.telegram.editMessageText(sentMessage.chat.id, sentMessage.message_id, undefined, currentText);
|
||
}
|
||
|
||
// Финальное меню после задержки
|
||
await delay(2000);
|
||
await ctx.telegram.editMessageText(
|
||
sentMessage.chat.id,
|
||
sentMessage.message_id,
|
||
undefined,
|
||
`🚨 Добро пожаловать в CampFireGG.Crime 🚨\n\n`,
|
||
Markup.inlineKeyboard([
|
||
[Markup.button.callback('💼 Задачи', 'crime_missions')],
|
||
[Markup.button.callback('📊 Профиль', 'rpg_profile')],
|
||
[Markup.button.callback('💰 ...', 'crime_market')],
|
||
])
|
||
)} else {
|
||
// Показываем только меню, если команда уже была введена
|
||
await ctx.reply(
|
||
`🚨 Добро пожаловать в CampFireGG.Crime 🚨\n\n`,
|
||
Markup.inlineKeyboard([
|
||
[Markup.button.callback('💼 Задачи', 'crime_missions')],
|
||
[Markup.button.callback('📊 Профиль', 'rpg_profile')],
|
||
[Markup.button.callback('💰 ...', 'crime_market')],
|
||
])
|
||
);
|
||
}
|
||
});
|
||
|
||
// Обработчики кнопок
|
||
rpg.action('crime_missions', async (ctx) => {
|
||
await ctx.answerCbQuery();
|
||
await ctx.editMessageText(`💼 **Задачи:**\n`,
|
||
Markup.inlineKeyboard([
|
||
[{text: 'Карманные кражи [1 lvl.]', callback_data: `POCKET_ACTION`}],
|
||
[{text: 'Магазин [5 lvl.]', callback_data: `SHOP_ACTION`}],
|
||
//[{text: 'Банкомат', callback_data: `WIP`}],
|
||
// [{text: 'Банковское отделение', callback_data: `WIP`}],
|
||
//[{text: 'Угон', callback_data: `WIP`}],
|
||
// [{text: 'Ювелирка', callback_data: `WIP`}],
|
||
//[{text: 'Банк', callback_data: `WIP`}],
|
||
[{text: '🔙 Back to Menu', callback_data: `crime_menu`}]
|
||
]),
|
||
);
|
||
});
|
||
|
||
rpg.action(`POCKET_ACTION`, async (ctx) => {
|
||
let user = await UserModel.findByPk(ctx.from.id)
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
let pocketsteal = character.pocketstealcd
|
||
if(character.level < 1) return ctx.editMessageText('Доступно с 1 уровня!')
|
||
if(character.stamina < 10) return ctx.editMessageText('Вы устали!')
|
||
let cooldown = utils.setCooldown(character, 3600, pocketsteal)
|
||
if (character.pocketstealcd > cooldown.currentTime) return ctx.editMessageText(`📛 Данное действие будет доступно через ${cooldown.timeLeftInMinutes} мин.`);
|
||
character.pocketstealcd = cooldown.endTime
|
||
character.stamina -= 10
|
||
character.save()
|
||
ctx.editMessageText('Выберите объект', Markup.inlineKeyboard([
|
||
[
|
||
{text: 'Карман', callback_data: `POCKET_TARGET`},
|
||
{text: 'Бумажник', callback_data: `POCKET_WALLET`},
|
||
{text: 'Сумка', callback_data: `POCKET_BAG`}
|
||
]
|
||
]))
|
||
});
|
||
|
||
rpg.action(`POCKET_TARGET`, async (ctx) => {
|
||
ctx.editMessageText('В кармане обнаружено', Markup.inlineKeyboard([
|
||
[
|
||
{text: 'Деньги', callback_data: `MONEY_IN_POCKET`},
|
||
{text: 'Телефон', callback_data: `PHONE`}
|
||
]
|
||
]))
|
||
});
|
||
|
||
rpg.action(`MONEY_IN_POCKET`, async (ctx) => {
|
||
// Получаем пользователя и его персонажа
|
||
//let user = await UserModel.findByPk(ctx.from.id);
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
|
||
if (!character) {
|
||
return ctx.editMessageText('У вас нет персонажа. Создайте его перед началом.');
|
||
}
|
||
|
||
// Расчёт шанса на успешную кражу
|
||
let baseChance = 20; // Базовый шанс
|
||
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
|
||
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
|
||
if (randomRoll > chance) {
|
||
return ctx.editMessageText('Вы были замечены во время кражи.');
|
||
}
|
||
// Успешная кража
|
||
let moneyIn = utils.rand(5, 1000);
|
||
character.dirtymoney += moneyIn;
|
||
await character.save();
|
||
return ctx.editMessageText(`Вы успешно украли Ð${utils.spaces(moneyIn)} из кармана.`);
|
||
});
|
||
|
||
|
||
rpg.action(`PHONE`, async (ctx) => {
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
//let user = await UserModel.findByPk(ctx.from.id)
|
||
let property = await PropertyModel.findByPk(ctx.from.id);
|
||
// Расчёт шанса на успешную кражу
|
||
let baseChance = 20; // Базовый шанс
|
||
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
|
||
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
|
||
if(chance < randomRoll) return ctx.editMessageText('Вы были замечены во время кражи.');
|
||
let randPhone = utils.rand(1,10)
|
||
if (property.mobile.name) {
|
||
let dirtyMoney = Math.round(phones[randPhone].price/100*70)
|
||
character.dirtymoney += dirtyMoney
|
||
return await ctx.reply(`Вы сбыли украденный ${phones[randPhone].name} за Ð${utils.spaces(dirtyMoney)}`)
|
||
}
|
||
property.mobile = phones[randPhone]
|
||
await character.save()
|
||
await property.save()
|
||
return ctx.editMessageText(`Вы успешно украли ${phones[randPhone].name} из кармана.`)
|
||
});
|
||
|
||
rpg.action(`POCKET_WALLET`, async (ctx) => {
|
||
ctx.editMessageText('В бумажнике обнаружено', Markup.inlineKeyboard([
|
||
[
|
||
{text: 'Деньги', callback_data: `MONEY_IN_WALLET`},
|
||
{text: 'Карточка', callback_data: `CARD_IN_WALLET`}
|
||
]
|
||
]))
|
||
});
|
||
|
||
rpg.action(`MONEY_IN_WALLET`, async (ctx) => {
|
||
//let user = await UserModel.findByPk(ctx.from.id)
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
// Расчёт шанса на успешную кражу
|
||
let baseChance = 20; // Базовый шанс
|
||
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
|
||
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
|
||
if(chance < randomRoll) return ctx.editMessageText('Вы были замечены во время кражи.');
|
||
let moneyIn = utils.rand(1000, 10000)
|
||
character.dirtymoney += moneyIn
|
||
character.save()
|
||
return ctx.editMessageText(`Вы успешно украли Ð${utils.spaces(moneyIn)} из бумажника.`)
|
||
});
|
||
|
||
rpg.action(`CARD_IN_WALLET`, async (ctx) => {
|
||
//let user = await UserModel.findByPk(ctx.from.id)
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
let baseChance = 20; // Базовый шанс
|
||
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
|
||
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
|
||
if(chance < randomRoll) return ctx.editMessageText('Вы были замечены во время кражи.');
|
||
character.stealedcards += 1
|
||
character.save()
|
||
return ctx.editMessageText(`Вы успешно украли 💳 из бумажника.`)
|
||
});
|
||
|
||
rpg.action(`POCKET_BAG`, async (ctx) => {
|
||
//let user = await UserModel.findByPk(ctx.from.id)
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
let baseChance = 20; // Базовый шанс
|
||
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
|
||
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
|
||
if(chance < randomRoll) return ctx.editMessageText('Вы были замечены во время кражи.');
|
||
let times = utils.rand(2,20)
|
||
let moneyIn = 0
|
||
let text = ``
|
||
let values = 0
|
||
|
||
for(i=1; i<=times; i++){
|
||
randomize = utils.rand(1,100)
|
||
switch(randomize) {
|
||
case 2:
|
||
values = utils.rand(10000, 50000)
|
||
moneyIn += values
|
||
text += `+ Ð${utils.spaces(values)}\n`
|
||
break;
|
||
case 7:
|
||
values = utils.rand(10000, 100000)
|
||
moneyIn += values
|
||
text += `+ Ð${utils.spaces(values)}\n`
|
||
break;
|
||
default:
|
||
values = utils.rand(100, 3000)
|
||
moneyIn += values
|
||
text += `+ Ð${utils.spaces(values)}\n`
|
||
break;
|
||
}
|
||
}
|
||
character.dirtymoney += moneyIn
|
||
character.save()
|
||
return ctx.editMessageText(`Вы успешно украли сумку и сбыли все ценности из нее:\n${text}\nОбщий куш: Ð${utils.spaces(moneyIn)}`)
|
||
});
|
||
|
||
rpg.action('crime_menu', async (ctx) => {
|
||
await ctx.answerCbQuery();
|
||
await ctx.editMessageText(
|
||
`💻 **Crime.net Menu**`,
|
||
Markup.inlineKeyboard([
|
||
[Markup.button.callback('💼 Задачи', 'crime_missions')],
|
||
[Markup.button.callback('📊 Профиль', 'crime_stats')],
|
||
[Markup.button.callback('💰 ...', 'crime_market')],
|
||
])
|
||
);
|
||
});
|
||
|
||
rpg.action('SHOP_ACTION', async (ctx) => {
|
||
console.log('1')
|
||
let user = await UserModel.findByPk(ctx.from.id)
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
//let property = await PropertyModel.findByPk(ctx.from.id);
|
||
if(character.level < 5) return ctx.editMessageText('Доступно с 5 уровня!')
|
||
//if(property.weapon == 0) return ctx.editMessageText('Для данного задания нужен ствол.')
|
||
if(character.stamina < 25) return ctx.editMessageText('Вы устали!')
|
||
let shoprobcd = character.shoprobcd
|
||
let cooldown = utils.setCooldown(character, 3600, shoprobcd)
|
||
if (character.shoprobcd > cooldown.currentTime) return ctx.editMessageText(`📛 Данное действие будет доступно через ${cooldown.timeLeftInMinutes} мин.`);
|
||
character.shoprobcd = cooldown.endTime
|
||
character.stamina -= 25
|
||
character.save()
|
||
return ctx.editMessageText('Стадии:', Markup.inlineKeyboard([
|
||
[{text: 'Взлом кассы', callback_data: `SHOP_CASH_BREAK`}],
|
||
[{text: 'Разбить кассу', callback_data: `SHOP_CASH_SMASH`}]
|
||
]))
|
||
});
|
||
|
||
rpg.action(`SHOP_CASH_BREAK`, async (ctx) => {
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
let baseChance = 20; // Базовый шанс
|
||
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
|
||
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
|
||
let cashIn = utils.rand(1000, 10000)
|
||
let timer = 1000
|
||
if(chance < randomRoll) {
|
||
const keyboard = generateKeyboard();
|
||
ctx.deleteMessage()
|
||
return ctx.reply('Касса закрыта, вы начали взлом замка:', keyboard);
|
||
//ctx.editMessageText('Вы начали взлом кассы.');
|
||
//return ctx.scene.enter('LOCKPICK')
|
||
}
|
||
for(i=0; i<utils.rand(6,15);i++){
|
||
setTimeout(() => {
|
||
cashIn += utils.rand(1000, 10000)
|
||
ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${utils.spaces(cashIn)}`)
|
||
}, timer)
|
||
timer += 500
|
||
}
|
||
setTimeout(() => {
|
||
character.dirtymoney += cashIn
|
||
character.save()
|
||
return ctx.editMessageText(`Вы достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([
|
||
[{text: 'Завершить ограбление', callback_data: `SHOP_END`}]
|
||
]))
|
||
}, timer+300)
|
||
});
|
||
|
||
rpg.action(`SHOP_CASH_SMASH`, async (ctx) => {
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
let baseChance = 20; // Базовый шанс
|
||
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
|
||
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
|
||
let cashIn = utils.rand(1000, 10000)
|
||
let timer = 1000
|
||
if(chance < randomRoll) {
|
||
return ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация. Вы сбежали.')
|
||
}
|
||
ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация.')
|
||
for(i=0; i<utils.rand(3,10);i++){
|
||
setTimeout(() => {
|
||
cashIn += utils.rand(500, 5000)
|
||
ctx.editMessageText(`⏏️ Вы в спешке достали из кассы: Ð${utils.spaces(cashIn)}`)
|
||
}, timer)
|
||
timer += 500
|
||
}
|
||
setTimeout(() => {
|
||
character.dirtymoney += cashIn
|
||
character.save()
|
||
return ctx.editMessageText(`Вы в спешке достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([
|
||
[{text: 'Завершить ограбление', callback_data: `SHOP_END`}]
|
||
]))
|
||
}, timer+300)
|
||
});
|
||
|
||
rpg.action(`SHOP_CASH_BREAK_SUCCESS`, async (ctx) => {
|
||
let user = await UserModel.findByPk(ctx.from.id)
|
||
let character = await CharacterModel.findByPk(ctx.from.id);
|
||
delete attempts[ctx.from.id];
|
||
let cashIn = utils.rand(1000, 10000)
|
||
let timer = 100
|
||
for(i=0; i<utils.rand(6,15);i++){
|
||
setTimeout(() => {
|
||
cashIn += utils.rand(3000, 10000)
|
||
ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${utils.spaces(cashIn)}`)
|
||
}, timer)
|
||
timer += 500
|
||
}
|
||
setTimeout(() => {
|
||
character.dirtymoney += cashIn
|
||
character.save()
|
||
return ctx.editMessageText(`Вы достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([
|
||
[{text: 'Завершить ограбление', callback_data: `SHOP_END`}]
|
||
]))
|
||
}, timer+300)
|
||
});
|
||
|
||
rpg.action(`SHOP_END`, async (ctx) => {
|
||
return ctx.editMessageText('Ограбление завершено!')
|
||
});
|
||
|
||
const attempts = {}; // Храним количество попыток взлома для каждого пользователя
|
||
|
||
rpg.action(/lock_*/, async (ctx) => {
|
||
const userId = ctx.from.id;
|
||
const buttonId = ctx.update.callback_query.data;
|
||
|
||
// Если пользователя нет в списке попыток, добавляем его
|
||
if (!attempts[userId]) {
|
||
attempts[userId] = 0;
|
||
}
|
||
|
||
// Увеличиваем количество попыток
|
||
attempts[userId] += 1;
|
||
|
||
// Проверяем, не исчерпаны ли попытки
|
||
if (attempts[userId] >= 5) {
|
||
delete attempts[userId]; // Сбрасываем попытки после провала
|
||
return ctx.editMessageText('Взлом провалился. Замок остается нетронутым.');
|
||
}
|
||
|
||
// Ответ на нажатие кнопки
|
||
ctx.answerCbQuery(`Штифт не сдвинулся. Попыток осталось: ${5 - attempts[userId]}`);
|
||
removeButton(ctx, buttonId);
|
||
});
|
||
|
||
function generateKeyboard() {
|
||
const buttonsCount = 10;
|
||
const buttons = [];
|
||
const winButton = utils.rand(1, 10);
|
||
|
||
for (let i = 1; i <= buttonsCount; i++) {
|
||
if (i === winButton) {
|
||
buttons.push({ text: `🔒`, callback_data: `SHOP_CASH_BREAK_SUCCESS` });
|
||
} else {
|
||
buttons.push({ text: `🔒`, callback_data: `lock_${i}` });
|
||
}
|
||
}
|
||
|
||
const rows = [];
|
||
while (buttons.length > 0) {
|
||
rows.push(buttons.splice(0, 5)); // Разбиваем на подмассивы по 5 кнопок
|
||
}
|
||
console.log(rows)
|
||
return {
|
||
reply_markup: {
|
||
inline_keyboard: rows,
|
||
},
|
||
};
|
||
}
|
||
|
||
function removeButton(ctx, buttonId) {
|
||
const keyboard = ctx.update.callback_query.message.reply_markup.inline_keyboard;
|
||
|
||
for (let row of keyboard) {
|
||
for (let i = 0; i < row.length; i++) {
|
||
if (row[i].callback_data === buttonId) {
|
||
row[i].text = `🔓`;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
ctx.editMessageText('Взлом замка:', Markup.inlineKeyboard(keyboard));
|
||
}
|
||
|
||
// Восстановление здоровья (HP)
|
||
async function recoverHealth() {
|
||
const characters = await CharacterModel.findAll({
|
||
where: {
|
||
hp: {
|
||
[Op.lt]: 100, // Восстанавливаем только тем, у кого HP меньше 100
|
||
},
|
||
},
|
||
});
|
||
|
||
for (const character of characters) {
|
||
const recoveryRate = character.resilience; // Восстановление 10 HP за интервал
|
||
character.hp = Math.min(character.hp + recoveryRate, 100); // Не превышаем максимум
|
||
await character.save();
|
||
}
|
||
}
|
||
|
||
// Восстановление выносливости (стамины)
|
||
async function recoverStamina() {
|
||
const characters = await CharacterModel.findAll({
|
||
where: {
|
||
stamina: {
|
||
[Op.lt]: 100, // Восстанавливаем только тем, у кого стамина меньше 100
|
||
},
|
||
},
|
||
});
|
||
|
||
for (const character of characters) {
|
||
const recoveryRate = character.endurance; // Восстановление 5 стамины за интервал
|
||
character.stamina = Math.min(character.stamina + recoveryRate, 100); // Не превышаем максимум
|
||
await character.save();
|
||
}
|
||
}
|
||
|
||
// Периодическое выполнение задач
|
||
function startRecoveryIntervals() {
|
||
const interval = 5 * 1000; // Интервал в миллисекундах (например, 1 минута)
|
||
setInterval(recoverHealth, interval);
|
||
setInterval(recoverStamina, interval);
|
||
}
|
||
|
||
startRecoveryIntervals()
|
||
|
||
module.exports = rpg;
|