Visual Enchancements
This commit is contained in:
Degradin 2025-01-12 23:44:41 +03:00
parent aac3c0f21c
commit 4f1e3943b4
2 changed files with 407 additions and 405 deletions

168
bot.js
View File

@ -3,7 +3,7 @@ const { Telegraf, Scenes, session, Markup, Stage } = require('telegraf');
const { Op } = require('sequelize'); const { Op } = require('sequelize');
const schedule = require('node-schedule'); const schedule = require('node-schedule');
const sequelize = require('./db'); // Подключение базы данных const sequelize = require('./db'); // Подключение базы данных
// Подключаем обработчики // Подключаем обработчики
const commands = require('./commands'); const commands = require('./commands');
const utils = require('./utils'); const utils = require('./utils');
const handlers = require('./handlers'); const handlers = require('./handlers');
@ -25,16 +25,16 @@ const {
SkillsModel, SkillsModel,
DailyModel DailyModel
} = global.config } = global.config
const bot = new Telegraf(process.env.BOT_TOKEN) const bot = new Telegraf(process.env.BOT_TOKEN)
const rpg = require('./rpg'); // Подключение RPG-механик const rpg = require('./rpg'); // Подключение RPG-механик
const crime = require('./scenes/crime') const crime = require('./scenes/crime')
const pocketsteal = require('./scenes/pocketsteal') const pocketsteal = require('./scenes/pocketsteal')
const shop = require('./scenes/shop') const shop = require('./scenes/shop')
const pve = require('./scenes/pve') const pve = require('./scenes/pve')
const newpve = require('./scenes/newpve') const newpve = require('./scenes/newpve')
const stage = new Scenes.Stage([crime, pocketsteal, shop, pve, newpve]); const stage = new Scenes.Stage([crime, pocketsteal, shop, pve, newpve]);
const start = async () => { const start = async () => {
try { try {
// Подключаемся к базе данных // Подключаемся к базе данных
await sequelize.authenticate(); await sequelize.authenticate();
@ -52,29 +52,29 @@ const newpve = require('./scenes/newpve')
} }
bot.telegram.setMyCommands([{ bot.telegram.setMyCommands([{
command: "pay", command: "pay",
description: "Перевести указанному пользователю сумму." description: "Перевести указанному пользователю сумму."
}, },
{ {
command: "buy", command: "buy",
description: "Приобрести указанное имущество." description: "Приобрести указанное имущество."
}, },
{ {
command: "business", command: "business",
description: "Создать организацию." description: "Создать организацию."
}, },
{ {
command: "invite", command: "invite",
description: "Пригласить пользователя в организацию." description: "Пригласить пользователя в организацию."
}, },
{ {
command: "percent", command: "percent",
description: "Установить пользователю процент заработка." description: "Установить пользователю процент заработка."
}, },
{ {
command: "report", command: "report",
description: "Создать жалобу/обращение/идею." description: "Создать жалобу/обращение/идею."
} }
]) ])
bot.use(stage.middleware()) bot.use(stage.middleware())
@ -82,25 +82,25 @@ bot.use(rpg)
bot.use( bot.use(
session({ session({
getSessionKey: (ctx) => { getSessionKey: (ctx) => {
if ((ctx.from && ctx.chat && ctx.chat.id === ctx.from.id) || (!ctx.chat && ctx.from)) { if ((ctx.from && ctx.chat && ctx.chat.id === ctx.from.id) || (!ctx.chat && ctx.from)) {
return `user:${ctx.from.id}` return `user:${ctx.from.id}`
} else if (ctx.from && ctx.chat) { } else if (ctx.from && ctx.chat) {
return `${ctx.from.id}:${ctx.chat.id}` return `${ctx.from.id}:${ctx.chat.id}`
}
return ctx.update.update_id
} }
return ctx.update.update_id
}
}) })
) )
bot.use(stage) bot.use(stage)
bot.use(utils.stats) bot.use(utils.stats)
bot.use(async (ctx, next) => { bot.use(async (ctx, next) => {
bot.context.config = require('./ctxconfig.json') bot.context.config = require('./ctxconfig.json')
let id = ctx.from.id let id = ctx.from.id
let username = ctx.from.username let username = ctx.from.username
if(username == null) username = ctx.from.id if (username == null) username = ctx.from.id
switch(ctx.updateType){ switch (ctx.updateType) {
case `message`: case `message`:
console.log(utils.getCurrentTime() + `: ` + username + `: ` + ctx.update.message.text) console.log(utils.getCurrentTime() + `: ` + username + `: ` + ctx.update.message.text)
break; break;
@ -124,9 +124,9 @@ bot.use(async (ctx, next) => {
name: ctx.from.first_name name: ctx.from.first_name
}) })
} else { } else {
user.name = ctx.from.first_name user.name = ctx.from.first_name
if(user.username === null) user.username = ctx.from.id if (user.username === null) user.username = ctx.from.id
user.save() user.save()
} }
if (property === null) { if (property === null) {
await PropertyModel.create({ await PropertyModel.create({
@ -162,26 +162,26 @@ bot.use(async (ctx, next) => {
const timeoutPromise = new Promise((resolve, reject) => { const timeoutPromise = new Promise((resolve, reject) => {
setTimeout(() => { setTimeout(() => {
reject(new Error('timeout')) reject(new Error('timeout'))
}, 1000 * 5) }, 1000 * 5)
}) })
const nextPromise = next() const nextPromise = next()
.then(() => { .then(() => {
const ms = Date.now() - start const ms = Date.now() - start
}) })
.catch((error) => {
handleError(error, ctx)
})
return Promise.race([timeoutPromise, nextPromise])
.catch((error) => { .catch((error) => {
if (error.message === 'timeout') { handleError(error, ctx)
console.error('timeout', ctx.update) })
return false
}
return true return Promise.race([timeoutPromise, nextPromise])
.catch((error) => {
if (error.message === 'timeout') {
console.error('timeout', ctx.update)
return false
}
return true
}) })
}) })
@ -221,7 +221,7 @@ bot.hears('Криминал', async (ctx) => {
}) })
bot.hears('промка', async(ctx) => { bot.hears('промка', async (ctx) => {
generatePromo() generatePromo()
}); });
@ -343,13 +343,13 @@ bot.action(/{"action": "sueta_*/, async (ctx) => {
console.log(data.car) console.log(data.car)
let user = await UserModel.findByPk(ctx.from.id) let user = await UserModel.findByPk(ctx.from.id)
let property = await PropertyModel.findByPk(ctx.from.id) let property = await PropertyModel.findByPk(ctx.from.id)
switch(data.action){ switch (data.action) {
case `sueta_accept`: case `sueta_accept`:
user.money += data.carprice user.money += data.carprice
await ctx.editMessageText(` ${data.carprice}`) await ctx.editMessageText(` ${data.carprice}`)
break; break;
case `sueta_refuse`: case `sueta_refuse`:
user.money += Math.round(property.car.price/2) user.money += Math.round(property.car.price / 2)
property.car = { property.car = {
name: data.carname, name: data.carname,
price: data.carprice price: data.carprice
@ -553,8 +553,8 @@ bot.action('my_enterprises', async (ctx) => {
return await ctx.reply('У вас нет предприятий.'); return await ctx.reply('У вас нет предприятий.');
} }
let metallPrice = await ResourcePriceModel.findOne({ let metallPrice = await ResourcePriceModel.findOne({
where: { resource: "metall" } where: { resource: "metall" }
}); });
let message = `🏭 Мои предприятия:\n\n`; let message = `🏭 Мои предприятия:\n\n`;
const buttons = []; const buttons = [];
@ -574,7 +574,7 @@ bot.action('my_enterprises', async (ctx) => {
if (!truck) { if (!truck) {
enterpriseButtons.push({ text: `🛻 ID: ${id}`, callback_data: `hire_truck_${id}` }); enterpriseButtons.push({ text: `🛻 ID: ${id}`, callback_data: `hire_truck_${id}` });
}else{ } else {
enterpriseButtons.push({ text: `🚛 ID: ${id}`, callback_data: `upgrade_truck_${id}` }); enterpriseButtons.push({ text: `🚛 ID: ${id}`, callback_data: `upgrade_truck_${id}` });
} }
@ -586,7 +586,7 @@ bot.action('my_enterprises', async (ctx) => {
buttons.push(enterpriseButtons); buttons.push(enterpriseButtons);
} }
message += `\n\n📈 - Улучшить\n🛻 - Купить грузовик [~${utils.spaces(metallPrice.price*700)} руб.]\n🚛 - Улучшить грузовик\n💰 - Продать ресурсы с предприятия\n🔄 - Перевезти все на склад` message += `\n\n📈 - Улучшить\n🛻 - Купить грузовик [~${utils.spaces(metallPrice.price * 700)} руб.]\n🚛 - Улучшить грузовик\n💰 - Продать ресурсы с предприятия\n🔄 - Перевезти все на склад`
buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]); buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]);
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize()); return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
@ -605,7 +605,7 @@ bot.action('build_enterprise', async (ctx) => {
}); });
if (enterprises.length >= 5) { if (enterprises.length >= 5) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Вы достигли максимального числа предприятий.', {show_alert: true}); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Вы достигли максимального числа предприятий.', { show_alert: true });
} }
// Получаем текущие цены из базы данных // Получаем текущие цены из базы данных
@ -652,7 +652,7 @@ bot.action(/build_(wood|coal|oil|metall|gold|diamond)/, async (ctx) => {
// Проверка, есть ли достаточно денег у пользователя // Проверка, есть ли достаточно денег у пользователя
if (user.money < price) { if (user.money < price) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас недостаточно средств для постройки предприятия. Необходимо ${price} руб.`, {show_alert: true}) return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас недостаточно средств для постройки предприятия. Необходимо ${price} руб.`, { show_alert: true })
} }
// Строим предприятие // Строим предприятие
@ -784,7 +784,7 @@ bot.action('transfer_resources', async (ctx) => {
const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } }); const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } });
if (!warehouse) { if (!warehouse) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id,'У вас нет единого склада.'); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'У вас нет единого склада.');
} }
const enterprises = await EnterpriseModel.findAll({ const enterprises = await EnterpriseModel.findAll({
@ -814,20 +814,20 @@ bot.action(/transfer_from_(\d+)/, async (ctx) => {
const { currentResources, resourceType, playerId } = enterprise; const { currentResources, resourceType, playerId } = enterprise;
if (currentResources === 0) { if (currentResources === 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для перевода.'); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для перевода.');
} }
const warehouse = await WarehouseModel.findOne({ where: { playerId } }); const warehouse = await WarehouseModel.findOne({ where: { playerId } });
if (!warehouse) { if (!warehouse) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'У вас нет склада для перевода ресурсов.'); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'У вас нет склада для перевода ресурсов.');
} }
const freeCapacity = warehouse.capacity - getWarehouseUsedCapacity(warehouse); const freeCapacity = warehouse.capacity - getWarehouseUsedCapacity(warehouse);
const transferAmount = Math.min(currentResources, freeCapacity); const transferAmount = Math.min(currentResources, freeCapacity);
if (transferAmount === 0) { if (transferAmount === 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Склад заполнен. Перевод невозможен.'); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Склад заполнен. Перевод невозможен.');
} }
// Перевод ресурсов // Перевод ресурсов
@ -873,7 +873,7 @@ bot.action(/upgrade_(\d+)/, async (ctx) => {
}); });
let upgradeCost = resourcePrice.price * 1.5 * 10 * 24 * 7 // Стоимость улучшения зависит от уровня let upgradeCost = resourcePrice.price * 1.5 * 10 * 24 * 7 // Стоимость улучшения зависит от уровня
if (user.money < upgradeCost) { if (user.money < upgradeCost) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас недостаточно средств для прокачки предприятия. Необходимо ${upgradeCost} руб.`) return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас недостаточно средств для прокачки предприятия. Необходимо ${upgradeCost} руб.`)
} }
// Прокачка: повышение уровня и эффективности // Прокачка: повышение уровня и эффективности
@ -994,7 +994,7 @@ bot.action(/sell_all_(\d+)/, async (ctx) => {
const totalPrice = currentResources * resourcePrice.price; const totalPrice = currentResources * resourcePrice.price;
if (currentResources === 0) { if (currentResources === 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для продажи.'); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для продажи.');
} }
await ctx.reply( await ctx.reply(
@ -1021,7 +1021,7 @@ bot.action(/confirm_ressell_(\d+)/, async (ctx) => {
const totalPrice = currentResources * resourcePrice.price; const totalPrice = currentResources * resourcePrice.price;
if (currentResources === 0) { if (currentResources === 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для продажи.'); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для продажи.');
} }
// Обновление баланса игрока // Обновление баланса игрока
@ -1119,16 +1119,16 @@ bot.action(/hire_truck_(\d+)/, async (ctx) => {
}); });
if (existingTruck) { if (existingTruck) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас уже есть грузовик для предприятия ${enterprise.name}.`); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас уже есть грузовик для предприятия ${enterprise.name}.`);
} }
const resourcePrice = await ResourcePriceModel.findOne({ where: { resource: 'metall' } }); const resourcePrice = await ResourcePriceModel.findOne({ where: { resource: 'metall' } });
if (!resourcePrice) { if (!resourcePrice) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Не удалось получить цену ресурса.'); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Не удалось получить цену ресурса.');
} }
if (user.money < resourcePrice.price*700) { if (user.money < resourcePrice.price * 700) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `Недостаточно средств. Стоимость грузовика: ${utils.spaces(resourcePrice.price*700)} руб.`); return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `Недостаточно средств. Стоимость грузовика: ${utils.spaces(resourcePrice.price * 700)} руб.`);
} }
await user.update({ money: user.money - (resourcePrice.price*700) }) await user.update({ money: user.money - (resourcePrice.price * 700) })
// Создаем новый грузовик // Создаем новый грузовик
const newTruck = await TruckModel.create({ const newTruck = await TruckModel.create({
enterpriseId: enterprise.id, enterpriseId: enterprise.id,
@ -1447,7 +1447,7 @@ const spinSlots = async (ctx, bet, user) => {
let resultMessage = `🎰 Итог:\n${finalIcons.join(' | ')}\n\n`; let resultMessage = `🎰 Итог:\n${finalIcons.join(' | ')}\n\n`;
if (winMultiplier > 0) { if (winMultiplier > 0) {
const winnings = bet * winMultiplier; const winnings = bet * winMultiplier;
utils.giveExp(user, winMultiplier*10) utils.giveExp(user, winMultiplier * 10)
user.money += winnings; user.money += winnings;
await user.save(); await user.save();
console.log(`Win: ${winnings}`) console.log(`Win: ${winnings}`)

562
rpg.js
View File

@ -1,39 +1,39 @@
const { Telegraf, Scenes, session, Markup, Stage, Composer } = require('telegraf'); const { Telegraf, Scenes, session, Markup, Stage, Composer } = require('telegraf');
const schedule = require('node-schedule'); const schedule = require('node-schedule');
const { faker, fakerRU } = require('@faker-js/faker'); const { faker, fakerRU } = require('@faker-js/faker');
// Подключаем необходимые библиотеки // Подключаем необходимые библиотеки
const { Op } = require('sequelize'); const { Op } = require('sequelize');
const sequelize = require('./db'); // Подключение базы данных const sequelize = require('./db'); // Подключение базы данных
// Подключаем обработчики // Подключаем обработчики
const utils = require('./utils'); const utils = require('./utils');
const handlers = require('./handlers'); const handlers = require('./handlers');
const { const {
phones, phones,
expToUp, expToUp,
UserModel, UserModel,
CharacterModel, CharacterModel,
InventoryModel, InventoryModel,
ItemsModel, ItemsModel,
Enemy, Enemy,
Location, Location,
Battle, Battle,
StolenCardsModel, StolenCardsModel,
WorldModel, WorldModel,
PropertyModel, PropertyModel,
AFKPropertyModel, AFKPropertyModel,
BusinessModel, BusinessModel,
BlockModel, BlockModel,
EnterpriseModel, EnterpriseModel,
WarehouseModel, WarehouseModel,
TruckModel, TruckModel,
ResourcePriceModel, ResourcePriceModel,
SkillsModel, SkillsModel,
DailyModel DailyModel
} = global.config } = global.config
const rpg = new Composer(); const rpg = new Composer();
rpg.use(async (ctx, next) => { rpg.use(async (ctx, next) => {
if(ctx.update.edited_channel_post) return console.log(`[RPG] Channel post updated`); if (ctx.update.edited_channel_post) return console.log(`[RPG] Channel post updated`);
let id = ctx.from.id let id = ctx.from.id
let username = ctx.from.username; let username = ctx.from.username;
if (username == null) username = ctx.from.id; if (username == null) username = ctx.from.id;
@ -61,27 +61,27 @@ rpg.use(async (ctx, next) => {
}); });
rpg.hears('RPG', async (ctx) => { rpg.hears('RPG', async (ctx) => {
let message = `Меню:\n`; let message = `Меню:\n`;
const buttons = []; const buttons = [];
buttons.push([{ text: 'Мой Персонаж', callback_data: 'rpg_profile' }]); buttons.push([{ text: 'Мой Персонаж', callback_data: 'rpg_profile' }]);
return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize()); return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize());
}); });
rpg.action('rpg_profile', async (ctx) => { rpg.action('rpg_profile', async (ctx) => {
const telegramId = ctx.from.id; const telegramId = ctx.from.id;
// Ищем персонажа // Ищем персонажа
const character = await CharacterModel.findOne({ where: { telegram_id: telegramId } }); const character = await CharacterModel.findOne({ where: { telegram_id: telegramId } });
const stolenCards = await StolenCardsModel.findAll({ const stolenCards = await StolenCardsModel.findAll({
where: { userId: character.telegram_id } where: { userId: character.telegram_id }
}); });
if (!character) { if (!character) {
return ctx.reply('Персонаж не найден. Создайте нового персонажа, чтобы начать игру!'); return ctx.reply('Персонаж не найден. Создайте нового персонажа, чтобы начать игру!');
} }
// Формируем профиль // Формируем профиль
const profile = ` const profile = `
🎭 Профиль персонажа 🎭 Профиль персонажа
👤 Имя: ${character.name || 'Не указано'} 👤 Имя: ${character.name || 'Не указано'}
@ -99,17 +99,17 @@ rpg.action('rpg_profile', async (ctx) => {
💰 Баланс: ${utils.spaces(character.dirtymoney)}Ð 💰 Баланс: ${utils.spaces(character.dirtymoney)}Ð
🃏 Украденные карты: ${stolenCards.length} 🃏 Украденные карты: ${stolenCards.length}
`; `;
const buttons = [ const buttons = [
[Markup.button.callback('💳 Карточки', 'view_cards')], [Markup.button.callback('💳 Карточки', 'view_cards')],
[Markup.button.callback('🎒 Инвентарь', 'inventory')], [Markup.button.callback('🎒 Инвентарь', 'inventory')],
]; ];
if (character.firePoints >= 1) { if (character.firePoints >= 1) {
buttons.push([Markup.button.callback(' Распределить очки', 'fire_distribute')]); buttons.push([Markup.button.callback(' Распределить очки', 'fire_distribute')]);
} }
buttons.push([Markup.button.callback('🔙 В меню', 'crime_menu')]); buttons.push([Markup.button.callback('🔙 В меню', 'crime_menu')]);
// Отправляем сообщение // Отправляем сообщение
ctx.editMessageText(profile.trim(), Markup.inlineKeyboard(buttons)); ctx.editMessageText(profile.trim(), Markup.inlineKeyboard(buttons));
}); });
// Основная команда для вывода кнопок распределения F.I.R.E. // Основная команда для вывода кнопок распределения F.I.R.E.
@ -209,7 +209,7 @@ const usersCrimeNet = new Set();
rpg.hears('CampFireGG.Crime', async (ctx) => { rpg.hears('CampFireGG.Crime', async (ctx) => {
const userId = ctx.from.id; const userId = ctx.from.id;
const character = await CharacterModel.findOne({ where: { telegram_id: userId } }); const character = await CharacterModel.findOne({ where: { telegram_id: userId } });
if (!usersCrimeNet.has(userId) && character.level === 1){ if (!usersCrimeNet.has(userId) && character.level === 1) {
// Если пользователь вводит команду впервые // Если пользователь вводит команду впервые
usersCrimeNet.add(userId); usersCrimeNet.add(userId);
const username = ctx.from.username || 'User'; const username = ctx.from.username || 'User';
@ -218,12 +218,12 @@ rpg.hears('CampFireGG.Crime', async (ctx) => {
// Сообщение для симуляции // Сообщение для симуляции
const lines = [ const lines = [
`${sshCommand}`, `${sshCommand}`,
`> Connecting to secure servers with RSA key...`, `> Connecting to secure servers with RSA key...`,
`> Authentication in progress...`, `> Authentication in progress...`,
`> User "${username}" identified.`, `> User "${username}" identified.`,
`> Accessing CampFireGG.Crime...`, `> Accessing CampFireGG.Crime...`,
`> Connection established. Welcome, ${username}.`, `> Connection established. Welcome, ${username}.`,
]; ];
// Отправляем первое сообщение // Отправляем первое сообщение
@ -234,18 +234,18 @@ rpg.hears('CampFireGG.Crime', async (ctx) => {
let index = 0; let index = 0;
while (index < lines[0].length) { while (index < lines[0].length) {
const blockSize = Math.floor(Math.random() * 3) + 2; // Генерируем блок от 2 до 4 символов const blockSize = Math.floor(Math.random() * 3) + 2; // Генерируем блок от 2 до 4 символов
currentText += lines[0].slice(index, index + blockSize); // Добавляем блок текста currentText += lines[0].slice(index, index + blockSize); // Добавляем блок текста
index += blockSize; // Увеличиваем индекс index += blockSize; // Увеличиваем индекс
await ctx.telegram.editMessageText(sentMessage.chat.id, sentMessage.message_id, undefined, currentText); await ctx.telegram.editMessageText(sentMessage.chat.id, sentMessage.message_id, undefined, currentText);
await delay(100); // Задержка между блоками await delay(100); // Задержка между блоками
} }
// Последующие строки добавляются полностью, по одной // Последующие строки добавляются полностью, по одной
for (let i = 1; i < lines.length; i++) { for (let i = 1; i < lines.length; i++) {
await delay(1500); // Задержка между строками await delay(1500); // Задержка между строками
currentText += `\n${lines[i]}`; currentText += `\n${lines[i]}`;
await ctx.telegram.editMessageText(sentMessage.chat.id, sentMessage.message_id, undefined, currentText); await ctx.telegram.editMessageText(sentMessage.chat.id, sentMessage.message_id, undefined, currentText);
} }
// Финальное меню после задержки // Финальное меню после задержки
@ -253,31 +253,32 @@ rpg.hears('CampFireGG.Crime', async (ctx) => {
const buttons = [ const buttons = [
[Markup.button.callback('💼 Задачи', 'crime_missions')], [Markup.button.callback('💼 Задачи', 'crime_missions')],
[Markup.button.callback('📊 Профиль', 'rpg_profile')], [Markup.button.callback('📊 Профиль', 'rpg_profile')],
]; ];
//buttons.push([Markup.button.callback('💳 Карточки', 'view_cards')]); //buttons.push([Markup.button.callback('💳 Карточки', 'view_cards')]);
// Добавляем кнопку сообщения, если уровень персонажа равен 1 // Добавляем кнопку сообщения, если уровень персонажа равен 1
if (character && character.level === 1) { if (character && character.level === 1) {
buttons.push([Markup.button.callback('📩 (1) Сообщение', '1st_message')]); buttons.push([Markup.button.callback('📩 (1) Сообщение', '1st_message')]);
} }
await ctx.telegram.editMessageText( await ctx.telegram.editMessageText(
sentMessage.chat.id, sentMessage.chat.id,
sentMessage.message_id, sentMessage.message_id,
undefined, undefined,
`🚨 Добро пожаловать в CampFireGG.Crime 🚨\n\n`, `🚨 Добро пожаловать в CampFireGG.Crime 🚨\n\n`,
Markup.inlineKeyboard(buttons) Markup.inlineKeyboard(buttons)
)} else { )
} else {
// Показываем только меню, если команда уже была введена // Показываем только меню, если команда уже была введена
await ctx.reply( await ctx.reply(
`🚨 Добро пожаловать в CampFireGG.Crime 🚨\n\n`, `🚨 Добро пожаловать в CampFireGG.Crime 🚨\n\n`,
Markup.inlineKeyboard([ Markup.inlineKeyboard([
[Markup.button.callback('💼 Задачи', 'crime_missions')], [Markup.button.callback('💼 Задачи', 'crime_missions')],
[Markup.button.callback('📊 Профиль', 'rpg_profile')], [Markup.button.callback('📊 Профиль', 'rpg_profile')],
[Markup.button.callback('💰 Магазин', 'shop')], [Markup.button.callback('💰 Магазин', 'shop')],
]) ])
); );
} }
}); });
@ -374,9 +375,9 @@ rpg.action(/limitbuy_/, async (ctx) => {
const items = await ItemsModel.findAll({ limit: 10 }); const items = await ItemsModel.findAll({ limit: 10 });
// Если у пользователя нет записей о попытках, создаем их // Если у пользователя нет записей о попытках, создаем их
if (!attempts[ctx.from.id]) { if (!attempts[ctx.from.id]) {
attempts[ctx.from.id] = 0; attempts[ctx.from.id] = 0;
} }
// Генерация кнопок с предметами // Генерация кнопок с предметами
const buttons = []; const buttons = [];
@ -406,16 +407,16 @@ rpg.action(/purchase_/, async (ctx) => {
} }
// Проверяем, не исчерпаны ли попытки // Проверяем, не исчерпаны ли попытки
if (attempts[ctx.from.id] >= 3) { if (attempts[ctx.from.id] >= 3) {
// Сбрасываем попытки и уничтожаем карточку // Сбрасываем попытки и уничтожаем карточку
delete attempts[ctx.from.id]; delete attempts[ctx.from.id];
await StolenCardsModel.destroy({ where: { id: cardId } }); await StolenCardsModel.destroy({ where: { id: cardId } });
return ctx.editMessageText( return ctx.editMessageText(
'❌ Все попытки исчерпаны! Карточка стала недействительной.' '❌ Все попытки исчерпаны! Карточка стала недействительной.'
); );
} }
// Если баланс карты меньше, чем цена товара, увеличиваем количество попыток // Если баланс карты меньше, чем цена товара, увеличиваем количество попыток
if (card.balance < item.price) { if (card.balance < item.price) {
@ -644,27 +645,27 @@ rpg.action(/brute_success_/, async (ctx) => {
// Обработчики кнопок // Обработчики кнопок
rpg.action('crime_missions', async (ctx) => { rpg.action('crime_missions', async (ctx) => {
await ctx.answerCbQuery(); await ctx.answerCbQuery();
await ctx.editMessageText(`💼 **Задачи:**\n Для карманных краж тебе не нужно ничего, главное не попадись.\n А вот после ограбления магазина в переулке не спрячешься, без тачки на миссию нельзя.`, await ctx.editMessageText(`💼 **Задачи:**\n Для карманных краж тебе не нужно ничего, главное не попадись.\n А вот после ограбления магазина в переулке не спрячешься, без тачки на миссию нельзя.`,
Markup.inlineKeyboard([ Markup.inlineKeyboard([
[{text: 'Карманные кражи [1 lvl.]', callback_data: `POCKET_ACTION`}], [{ text: 'Карманные кражи [1 lvl.]', callback_data: `POCKET_ACTION` }],
[{text: 'Магазин [5 lvl.]', callback_data: `SHOP_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: 'Угон', callback_data: `WIP`}],
// [{text: 'Ювелирка', callback_data: `WIP`}], // [{text: 'Ювелирка', callback_data: `WIP`}],
//[{text: 'Банк', callback_data: `WIP`}], //[{text: 'Банк', callback_data: `WIP`}],
[{text: '🔙 В меню', callback_data: `crime_menu`}] [{ text: '🔙 В меню', callback_data: `crime_menu` }]
]), ]),
); );
}); });
rpg.action(`POCKET_ACTION`, async (ctx) => { rpg.action(`POCKET_ACTION`, async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id) let user = await UserModel.findByPk(ctx.from.id)
let character = await CharacterModel.findByPk(ctx.from.id); let character = await CharacterModel.findByPk(ctx.from.id);
let pocketsteal = character.pocketstealcd let pocketsteal = character.pocketstealcd
if(character.level < 1) return ctx.editMessageText('Доступно с 1 уровня!') if (character.level < 1) return ctx.editMessageText('Доступно с 1 уровня!')
if(character.stamina < 10) return ctx.editMessageText('Вы устали!') if (character.stamina < 10) return ctx.editMessageText('Вы устали!')
let cooldown = utils.setCooldown(character, 3600, pocketsteal) let cooldown = utils.setCooldown(character, 3600, pocketsteal)
if (character.pocketstealcd > cooldown.currentTime) return ctx.editMessageText(`📛 Данное действие будет доступно через ${cooldown.timeLeftInMinutes} мин.`); if (character.pocketstealcd > cooldown.currentTime) return ctx.editMessageText(`📛 Данное действие будет доступно через ${cooldown.timeLeftInMinutes} мин.`);
character.pocketstealcd = cooldown.endTime character.pocketstealcd = cooldown.endTime
@ -672,20 +673,20 @@ rpg.action(`POCKET_ACTION`, async (ctx) => {
character.save() character.save()
ctx.editMessageText('Выберите объект', Markup.inlineKeyboard([ ctx.editMessageText('Выберите объект', Markup.inlineKeyboard([
[ [
{text: 'Карман', callback_data: `POCKET_TARGET`}, { text: 'Карман', callback_data: `POCKET_TARGET` },
{text: 'Бумажник', callback_data: `POCKET_WALLET`}, { text: 'Бумажник', callback_data: `POCKET_WALLET` },
{text: 'Сумка', callback_data: `POCKET_BAG`} { text: 'Сумка', callback_data: `POCKET_BAG` }
] ]
])) ]))
}); });
rpg.action(`POCKET_TARGET`, async (ctx) => { rpg.action(`POCKET_TARGET`, async (ctx) => {
ctx.editMessageText('В кармане обнаружено', Markup.inlineKeyboard([ ctx.editMessageText('В кармане обнаружено', Markup.inlineKeyboard([
[ [
{text: 'Деньги', callback_data: `MONEY_IN_POCKET`}, { text: 'Деньги', callback_data: `MONEY_IN_POCKET` },
{text: 'Телефон', callback_data: `PHONE`} { text: 'Телефон', callback_data: `PHONE` }
] ]
])) ]))
}); });
rpg.action(`MONEY_IN_POCKET`, async (ctx) => { rpg.action(`MONEY_IN_POCKET`, async (ctx) => {
@ -694,7 +695,7 @@ rpg.action(`MONEY_IN_POCKET`, async (ctx) => {
let character = await CharacterModel.findByPk(ctx.from.id); let character = await CharacterModel.findByPk(ctx.from.id);
if (!character) { if (!character) {
return ctx.editMessageText('У вас нет персонажа. Создайте его перед началом.'); return ctx.editMessageText('У вас нет персонажа. Создайте его перед началом.');
} }
// Расчёт шанса на успешную кражу // Расчёт шанса на успешную кражу
@ -702,8 +703,8 @@ rpg.action(`MONEY_IN_POCKET`, async (ctx) => {
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100 let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
if (randomRoll > chance) { if (randomRoll > chance) {
Exp(ctx, character, 1) Exp(ctx, character, 1)
return ctx.editMessageText('Вы были замечены во время кражи.'); return ctx.editMessageText('Вы были замечены во время кражи.');
} }
// Успешная кража // Успешная кража
let moneyIn = utils.rand(5, 1000); let moneyIn = utils.rand(5, 1000);
@ -722,30 +723,30 @@ rpg.action(`PHONE`, async (ctx) => {
let baseChance = 20; // Базовый шанс let baseChance = 20; // Базовый шанс
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100 let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
if(chance < randomRoll) { if (chance < randomRoll) {
Exp(ctx, character, 1) Exp(ctx, character, 1)
return ctx.editMessageText('Вы были замечены во время кражи.') return ctx.editMessageText('Вы были замечены во время кражи.')
} }
let randPhone = utils.rand(1,10) let randPhone = utils.rand(1, 10)
if (property.mobile.name) { if (property.mobile.name) {
let dirtyMoney = Math.round(phones[randPhone].price/100*70) let dirtyMoney = Math.round(phones[randPhone].price / 100 * 70)
Exp(ctx, character, character.intelligence + 10) Exp(ctx, character, character.intelligence + 10)
character.dirtymoney += dirtyMoney character.dirtymoney += dirtyMoney
return await ctx.reply(`Вы сбыли украденный ${phones[randPhone].name} за Ð${utils.spaces(dirtyMoney)}`) return await ctx.reply(`Вы сбыли украденный ${phones[randPhone].name} за Ð${utils.spaces(dirtyMoney)}`)
} }
property.mobile = phones[randPhone] property.mobile = phones[randPhone]
await character.save() await character.save()
await property.save() await property.save()
return ctx.editMessageText(`Вы успешно украли ${phones[randPhone].name} из кармана.`) return ctx.editMessageText(`Вы успешно украли ${phones[randPhone].name} из кармана.`)
}); });
rpg.action(`POCKET_WALLET`, async (ctx) => { rpg.action(`POCKET_WALLET`, async (ctx) => {
ctx.editMessageText('В бумажнике обнаружено', Markup.inlineKeyboard([ ctx.editMessageText('В бумажнике обнаружено', Markup.inlineKeyboard([
[ [
{text: 'Деньги', callback_data: `MONEY_IN_WALLET`}, { text: 'Деньги', callback_data: `MONEY_IN_WALLET` },
{text: 'Карточка', callback_data: `CARD_IN_WALLET`} { text: 'Карточка', callback_data: `CARD_IN_WALLET` }
] ]
])) ]))
}); });
rpg.action(`MONEY_IN_WALLET`, async (ctx) => { rpg.action(`MONEY_IN_WALLET`, async (ctx) => {
@ -755,7 +756,7 @@ rpg.action(`MONEY_IN_WALLET`, async (ctx) => {
let baseChance = 35; // Базовый шанс let baseChance = 35; // Базовый шанс
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100 let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
if(chance < randomRoll) { if (chance < randomRoll) {
Exp(ctx, character, 1) Exp(ctx, character, 1)
return ctx.editMessageText('Вы были замечены во время кражи.') return ctx.editMessageText('Вы были замечены во время кражи.')
} }
@ -772,7 +773,7 @@ rpg.action(`CARD_IN_WALLET`, async (ctx) => {
let baseChance = 20; // Базовый шанс let baseChance = 20; // Базовый шанс
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100 let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
if(chance < randomRoll) { if (chance < randomRoll) {
Exp(ctx, character, 2) Exp(ctx, character, 2)
return ctx.editMessageText('Вы были замечены во время кражи.') return ctx.editMessageText('Вы были замечены во время кражи.')
} }
@ -788,18 +789,18 @@ rpg.action(`POCKET_BAG`, async (ctx) => {
let baseChance = 20; // Базовый шанс let baseChance = 20; // Базовый шанс
let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума".
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100 let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
if(chance < randomRoll) { if (chance < randomRoll) {
Exp(ctx, character, 1) Exp(ctx, character, 1)
return ctx.editMessageText('Вы были замечены во время кражи.') return ctx.editMessageText('Вы были замечены во время кражи.')
} }
let times = utils.rand(2,20) let times = utils.rand(2, 20)
let moneyIn = 0 let moneyIn = 0
let text = `` let text = ``
let values = 0 let values = 0
for(i=1; i<=times; i++){ for (i = 1; i <= times; i++) {
randomize = utils.rand(1,100) randomize = utils.rand(1, 100)
switch(randomize) { switch (randomize) {
case 2: case 2:
values = utils.rand(10000, 50000) values = utils.rand(10000, 50000)
moneyIn += values moneyIn += values
@ -824,24 +825,24 @@ rpg.action(`POCKET_BAG`, async (ctx) => {
}); });
rpg.action('crime_menu', async (ctx) => { rpg.action('crime_menu', async (ctx) => {
await ctx.answerCbQuery(); await ctx.answerCbQuery();
await ctx.editMessageText( await ctx.editMessageText(
`💻 CampFireGG.Crime Menu`, `💻 CampFireGG.Crime Menu`,
Markup.inlineKeyboard([ Markup.inlineKeyboard([
[Markup.button.callback('💼 Задачи', 'crime_missions')], [Markup.button.callback('💼 Задачи', 'crime_missions')],
[Markup.button.callback('📊 Профиль', 'rpg_profile')], [Markup.button.callback('📊 Профиль', 'rpg_profile')],
[Markup.button.callback('💰 Магазин', 'shop')], [Markup.button.callback('💰 Магазин', 'shop')],
]) ])
); );
}); });
rpg.action('SHOP_ACTION', async (ctx) => { rpg.action('SHOP_ACTION', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id) let user = await UserModel.findByPk(ctx.from.id)
let character = await CharacterModel.findByPk(ctx.from.id); let character = await CharacterModel.findByPk(ctx.from.id);
let property = await PropertyModel.findByPk(ctx.from.id); let property = await PropertyModel.findByPk(ctx.from.id);
if(character.level < 5) return ctx.editMessageText('Доступно с 5 уровня!') if (character.level < 5) return ctx.editMessageText('Доступно с 5 уровня!')
if(property.car1 == 0) return ctx.editMessageText('Для данного задания нужна тачка.') if (property.car1 == 0) return ctx.editMessageText('Для данного задания нужна тачка.')
if(character.stamina < 25) return ctx.editMessageText('Вы устали!') if (character.stamina < 25) return ctx.editMessageText('Вы устали!')
let shoprobcd = character.shoprobcd let shoprobcd = character.shoprobcd
let cooldown = utils.setCooldown(character, 3600, shoprobcd) let cooldown = utils.setCooldown(character, 3600, shoprobcd)
if (character.shoprobcd > cooldown.currentTime) return ctx.editMessageText(`📛 Данное действие будет доступно через ${cooldown.timeLeftInMinutes} мин.`); if (character.shoprobcd > cooldown.currentTime) return ctx.editMessageText(`📛 Данное действие будет доступно через ${cooldown.timeLeftInMinutes} мин.`);
@ -849,9 +850,9 @@ rpg.action('SHOP_ACTION', async (ctx) => {
character.stamina -= 25 character.stamina -= 25
character.save() character.save()
return ctx.editMessageText('Стадии:', Markup.inlineKeyboard([ return ctx.editMessageText('Стадии:', Markup.inlineKeyboard([
[{text: 'Взлом кассы', callback_data: `SHOP_CASH_BREAK`}], [{ text: 'Взлом кассы', callback_data: `SHOP_CASH_BREAK` }],
[{text: 'Разбить кассу', callback_data: `SHOP_CASH_SMASH`}] [{ text: 'Разбить кассу', callback_data: `SHOP_CASH_SMASH` }]
])) ]))
}); });
rpg.action(`SHOP_CASH_BREAK`, async (ctx) => { rpg.action(`SHOP_CASH_BREAK`, async (ctx) => {
@ -861,28 +862,28 @@ rpg.action(`SHOP_CASH_BREAK`, async (ctx) => {
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100 let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
let cashIn = utils.rand(1000, 10000) let cashIn = utils.rand(1000, 10000)
let timer = 1000 let timer = 1000
if(chance < randomRoll) { if (chance < randomRoll) {
const keyboard = generateKeyboard(); const keyboard = generateKeyboard();
ctx.deleteMessage() ctx.deleteMessage()
return ctx.reply('Касса закрыта, вы начали взлом замка:', keyboard); return ctx.reply('Касса закрыта, вы начали взлом замка:', keyboard);
//ctx.editMessageText('Вы начали взлом кассы.'); //ctx.editMessageText('Вы начали взлом кассы.');
//return ctx.scene.enter('LOCKPICK') //return ctx.scene.enter('LOCKPICK')
} }
for(i=0; i<utils.rand(character.endurance, character.endurance + 15);i++){ for (i = 0; i < utils.rand(character.endurance, character.endurance + 15); i++) {
setTimeout(() => { setTimeout(() => {
cashIn += utils.rand(1000, 10000) cashIn += utils.rand(1000, 10000)
ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${utils.spaces(cashIn)}`) ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${utils.spaces(cashIn)}`)
}, timer) }, timer)
timer += 500 timer += 500
} }
setTimeout(() => { setTimeout(() => {
Exp(ctx, character, character.intelligence + 25) Exp(ctx, character, character.intelligence + 25)
character.dirtymoney += cashIn character.dirtymoney += cashIn
character.save() character.save()
return ctx.editMessageText(`Вы достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([ return ctx.editMessageText(`Вы достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([
[{text: 'Завершить ограбление', callback_data: `SHOP_END`}] [{ text: 'Завершить ограбление', callback_data: `SHOP_END` }]
])) ]))
}, timer+300) }, timer + 300)
}); });
rpg.action(`SHOP_CASH_SMASH`, async (ctx) => { rpg.action(`SHOP_CASH_SMASH`, async (ctx) => {
@ -892,26 +893,26 @@ rpg.action(`SHOP_CASH_SMASH`, async (ctx) => {
let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100 let randomRoll = utils.rand(0, 100); // Случайное число от 0 до 100
let cashIn = utils.rand(1000, 10000) let cashIn = utils.rand(1000, 10000)
let timer = 1000 let timer = 1000
if(chance < randomRoll) { if (chance < randomRoll) {
Exp(ctx, character, 1) Exp(ctx, character, 1)
return ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация. Вы сбежали.') return ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация. Вы сбежали.')
} }
ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация.') ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация.')
for(i=0; i<utils.rand(character.endurance, character.endurance + 8);i++){ for (i = 0; i < utils.rand(character.endurance, character.endurance + 8); i++) {
setTimeout(() => { setTimeout(() => {
cashIn += utils.rand(500, 5000) cashIn += utils.rand(500, 5000)
ctx.editMessageText(`⏏️ Вы в спешке достали из кассы: Ð${utils.spaces(cashIn)}`) ctx.editMessageText(`⏏️ Вы в спешке достали из кассы: Ð${utils.spaces(cashIn)}`)
}, timer) }, timer)
timer += 500 timer += 500
} }
setTimeout(() => { setTimeout(() => {
Exp(ctx, character, character.intelligence + 10) Exp(ctx, character, character.intelligence + 10)
character.dirtymoney += cashIn character.dirtymoney += cashIn
character.save() character.save()
return ctx.editMessageText(`Вы в спешке достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([ return ctx.editMessageText(`Вы в спешке достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([
[{text: 'Завершить ограбление', callback_data: `SHOP_END`}] [{ text: 'Завершить ограбление', callback_data: `SHOP_END` }]
])) ]))
}, timer+300) }, timer + 300)
}); });
rpg.action(`SHOP_CASH_BREAK_SUCCESS`, async (ctx) => { rpg.action(`SHOP_CASH_BREAK_SUCCESS`, async (ctx) => {
@ -920,21 +921,21 @@ rpg.action(`SHOP_CASH_BREAK_SUCCESS`, async (ctx) => {
delete attempts[ctx.from.id]; delete attempts[ctx.from.id];
let cashIn = utils.rand(1000, 10000) let cashIn = utils.rand(1000, 10000)
let timer = 100 let timer = 100
for(i=0; i<utils.rand(character.endurance, character.endurance + 15);i++){ for (i = 0; i < utils.rand(character.endurance, character.endurance + 15); i++) {
setTimeout(() => { setTimeout(() => {
cashIn += utils.rand(3000, 10000) cashIn += utils.rand(3000, 10000)
ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${utils.spaces(cashIn)}`) ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${utils.spaces(cashIn)}`)
}, timer) }, timer)
timer += 500 timer += 500
} }
setTimeout(() => { setTimeout(() => {
Exp(ctx, character, character.intelligence + 30) Exp(ctx, character, character.intelligence + 30)
character.dirtymoney += cashIn character.dirtymoney += cashIn
character.save() character.save()
return ctx.editMessageText(`Вы достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([ return ctx.editMessageText(`Вы достали из кассы Ð${utils.spaces(cashIn)}, пора валить.`, Markup.inlineKeyboard([
[{text: 'Завершить ограбление', callback_data: `SHOP_END`}] [{ text: 'Завершить ограбление', callback_data: `SHOP_END` }]
])) ]))
}, timer+300) }, timer + 300)
}); });
rpg.action(`SHOP_END`, async (ctx) => { rpg.action(`SHOP_END`, async (ctx) => {
@ -944,26 +945,26 @@ rpg.action(`SHOP_END`, async (ctx) => {
const attempts = {}; // Храним количество попыток взлома для каждого пользователя const attempts = {}; // Храним количество попыток взлома для каждого пользователя
rpg.action(/lock_*/, async (ctx) => { rpg.action(/lock_*/, async (ctx) => {
const userId = ctx.from.id; const userId = ctx.from.id;
const buttonId = ctx.update.callback_query.data; const buttonId = ctx.update.callback_query.data;
// Если пользователя нет в списке попыток, добавляем его // Если пользователя нет в списке попыток, добавляем его
if (!attempts[userId]) { if (!attempts[userId]) {
attempts[userId] = 0; attempts[userId] = 0;
} }
// Увеличиваем количество попыток // Увеличиваем количество попыток
attempts[userId] += 1; attempts[userId] += 1;
// Проверяем, не исчерпаны ли попытки // Проверяем, не исчерпаны ли попытки
if (attempts[userId] >= 5) { if (attempts[userId] >= 5) {
delete attempts[userId]; // Сбрасываем попытки после провала delete attempts[userId]; // Сбрасываем попытки после провала
return ctx.editMessageText('Взлом провалился. Замок остается нетронутым.'); return ctx.editMessageText('Взлом провалился. Замок остается нетронутым.');
} }
// Ответ на нажатие кнопки // Ответ на нажатие кнопки
ctx.answerCbQuery(`Штифт не сдвинулся. Попыток осталось: ${5 - attempts[userId]}`); ctx.answerCbQuery(`Штифт не сдвинулся. Попыток осталось: ${5 - attempts[userId]}`);
removeButton(ctx, buttonId); removeButton(ctx, buttonId);
}); });
rpg.action('inventory', async (ctx) => { rpg.action('inventory', async (ctx) => {
@ -1041,7 +1042,7 @@ rpg.action(/view_item_(\d+)/, async (ctx) => {
const buttons = [] const buttons = []
let message = ` ${item.name}\n` let message = ` ${item.name}\n`
message += ` 📜 ${item.description}\n\n 〰️Редкость: ${item.rarity}\n 🔤Тип: ${item.type}` message += ` 📜 ${item.description}\n\n 〰️Редкость: ${item.rarity}\n 🔤Тип: ${item.type}`
if (!item.equipped){ if (!item.equipped) {
buttons.push([Markup.button.callback(`🎯 Использовать ${item.name}`, `use_item_${item.id}`)]); buttons.push([Markup.button.callback(`🎯 Использовать ${item.name}`, `use_item_${item.id}`)]);
} }
if (item.equipped && item.canBeEquipped) { if (item.equipped && item.canBeEquipped) {
@ -1076,7 +1077,7 @@ rpg.action(/use_item_(\d+)/, async (ctx) => {
// Применяем эффекты предмета // Применяем эффекты предмета
if (item.effectData) { if (item.effectData) {
const resultMessages = processEffects(character, item.effectData, true); const resultMessages = processEffects(character, item.effectData, true);
await ctx.answerCbQuery(resultMessages, {show_alert: true}); await ctx.answerCbQuery(resultMessages, { show_alert: true });
} }
if (item.canBeEquipped && item.type != 'consumable') { if (item.canBeEquipped && item.type != 'consumable') {
@ -1118,28 +1119,28 @@ rpg.action('shop', async (ctx) => {
// Получаем текущую запись мира // Получаем текущую запись мира
const world = await WorldModel.findOne({ where: { id: 1 } }); const world = await WorldModel.findOne({ where: { id: 1 } });
if (!world) { if (!world) {
return ctx.reply('Магазин недоступен.'); return ctx.reply('Магазин недоступен.');
} }
// Получаем ID предметов, доступных в магазине // Получаем ID предметов, доступных в магазине
const { itemsInCrimeShop } = world; const { itemsInCrimeShop } = world;
if (!itemsInCrimeShop || itemsInCrimeShop.length === 0) { if (!itemsInCrimeShop || itemsInCrimeShop.length === 0) {
return ctx.reply('Магазин пуст!'); return ctx.reply('Магазин пуст!');
} }
// Загружаем только те предметы, ID которых есть в массиве // Загружаем только те предметы, ID которых есть в массиве
const items = await ItemsModel.findAll({ where: { id: itemsInCrimeShop } }); const items = await ItemsModel.findAll({ where: { id: itemsInCrimeShop } });
if (items.length === 0) { if (items.length === 0) {
return ctx.reply('Магазин пуст!'); return ctx.reply('Магазин пуст!');
} }
let message = 'Добро пожаловать в магазин! Здесь вы можете купить предметы:\n\n'; let message = 'Добро пожаловать в магазин! Здесь вы можете купить предметы:\n\n';
// Генерируем кнопки, каждая кнопка будет в отдельной строке // Генерируем кнопки, каждая кнопка будет в отдельной строке
const buttons = items.map((item) => [ const buttons = items.map((item) => [
Markup.button.callback(`${item.name} - ${item.price}`, `buy_item_${item.id}`) Markup.button.callback(`${item.name} - ${item.price}`, `buy_item_${item.id}`)
]); ]);
buttons.push([Markup.button.callback('🔙 В меню', 'crime_menu')]); buttons.push([Markup.button.callback('🔙 В меню', 'crime_menu')]);
@ -1153,7 +1154,7 @@ rpg.action(/buy_item_(\d+)/, async (ctx) => {
const inventory = await InventoryModel.findAll({ where: { telegram_id: ctx.from.id } }); const inventory = await InventoryModel.findAll({ where: { telegram_id: ctx.from.id } });
if (inventory.length >= 15) { if (inventory.length >= 15) {
return ctx.answerCbQuery('Инвентарь полон.', {show_alert: true}); return ctx.answerCbQuery('Инвентарь полон.', { show_alert: true });
} }
if (!item) { if (!item) {
@ -1167,7 +1168,7 @@ rpg.action(/buy_item_(\d+)/, async (ctx) => {
} }
if (character.balance < item.price) { if (character.balance < item.price) {
return ctx.answerCbQuery('У вас недостаточно средств для покупки этого предмета.', {show_alert: true}); return ctx.answerCbQuery('У вас недостаточно средств для покупки этого предмета.', { show_alert: true });
} }
// Снимаем деньги с баланса // Снимаем деньги с баланса
@ -1189,7 +1190,7 @@ rpg.action(/buy_item_(\d+)/, async (ctx) => {
}); });
await character.save(); await character.save();
ctx.answerCbQuery(`Вы успешно купили ${item.name} за ${item.price}₽!`, {show_alert: true}); ctx.answerCbQuery(`Вы успешно купили ${item.name} за ${item.price}₽!`, { show_alert: true });
}); });
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
@ -1330,77 +1331,77 @@ const processEffects = (character, effects, isEquipping) => {
}; };
function generateKeyboard() { function generateKeyboard() {
const buttonsCount = 10; const buttonsCount = 10;
const buttons = []; const buttons = [];
const winButton = utils.rand(1, 10); const winButton = utils.rand(1, 10);
for (let i = 1; i <= buttonsCount; i++) { for (let i = 1; i <= buttonsCount; i++) {
if (i === winButton) { if (i === winButton) {
buttons.push({ text: `🔒`, callback_data: `SHOP_CASH_BREAK_SUCCESS` }); buttons.push({ text: `🔒`, callback_data: `SHOP_CASH_BREAK_SUCCESS` });
} else { } else {
buttons.push({ text: `🔒`, callback_data: `lock_${i}` }); buttons.push({ text: `🔒`, callback_data: `lock_${i}` });
}
} }
}
const rows = []; const rows = [];
while (buttons.length > 0) { while (buttons.length > 0) {
rows.push(buttons.splice(0, 5)); // Разбиваем на подмассивы по 5 кнопок rows.push(buttons.splice(0, 5)); // Разбиваем на подмассивы по 5 кнопок
} }
console.log(rows) console.log(rows)
return { return {
reply_markup: { reply_markup: {
inline_keyboard: rows, inline_keyboard: rows,
}, },
}; };
} }
function removeButton(ctx, buttonId) { function removeButton(ctx, buttonId) {
const keyboard = ctx.update.callback_query.message.reply_markup.inline_keyboard; const keyboard = ctx.update.callback_query.message.reply_markup.inline_keyboard;
for (let row of keyboard) { for (let row of keyboard) {
for (let i = 0; i < row.length; i++) { for (let i = 0; i < row.length; i++) {
if (row[i].callback_data === buttonId) { if (row[i].callback_data === buttonId) {
row[i].text = `🔓`; row[i].text = `🔓`;
break; break;
} }
}
} }
}
ctx.editMessageText('Взлом замка:', Markup.inlineKeyboard(keyboard).resize()); ctx.editMessageText('Взлом замка:', Markup.inlineKeyboard(keyboard).resize());
} }
// Восстановление здоровья (HP) // Восстановление здоровья (HP)
async function recoverHealth() { async function recoverHealth() {
const characters = await CharacterModel.findAll({ const characters = await CharacterModel.findAll({
where: { where: {
hp: { hp: {
[Op.lt]: 100, // Восстанавливаем только тем, у кого HP меньше 100 [Op.lt]: 100, // Восстанавливаем только тем, у кого HP меньше 100
}, },
}, },
}); });
for (const character of characters) { for (const character of characters) {
const recoveryRate = character.resilience; // Восстановление 10 HP за интервал const recoveryRate = character.resilience; // Восстановление 10 HP за интервал
character.hp = Math.min(character.hp + recoveryRate, 100); // Не превышаем максимум character.hp = Math.min(character.hp + recoveryRate, 100); // Не превышаем максимум
await character.save(); await character.save();
} }
} }
// Восстановление выносливости (стамины) // Восстановление выносливости (стамины)
async function recoverStamina() { async function recoverStamina() {
const characters = await CharacterModel.findAll({ const characters = await CharacterModel.findAll({
where: { where: {
stamina: { stamina: {
[Op.lt]: 100, // Восстанавливаем только тем, у кого стамина меньше 100 [Op.lt]: 100, // Восстанавливаем только тем, у кого стамина меньше 100
}, },
}, },
}); });
for (const character of characters) { for (const character of characters) {
const recoveryRate = character.endurance; // Восстановление 5 стамины за интервал const recoveryRate = character.endurance; // Восстановление 5 стамины за интервал
character.stamina = Math.min(character.stamina + recoveryRate, 100); // Не превышаем максимум character.stamina = Math.min(character.stamina + recoveryRate, 100); // Не превышаем максимум
await character.save(); await character.save();
} }
} }
const reduceStealedCards = async () => { const reduceStealedCards = async () => {
@ -1439,10 +1440,10 @@ const reduceStealedCards = async () => {
async function generateCard(userId, balance) { async function generateCard(userId, balance) {
if(!Number(balance)){ if (!Number(balance)) {
balance = faker.finance.amount({dec: 0})*100 balance = faker.finance.amount({ dec: 0 }) * 100
console.log('Random balance: ' + balance) console.log('Random balance: ' + balance)
}else{ } else {
balance = Math.floor(balance); balance = Math.floor(balance);
console.log('Set balance: ' + balance) console.log('Set balance: ' + balance)
} }
@ -1469,21 +1470,22 @@ async function Exp(ctx, character, experience) {
character.exp += experience character.exp += experience
await ctx.sendMessage(`❇️ +${experience} exp.`) await ctx.sendMessage(`❇️ +${experience} exp.`)
await character.save() await character.save()
for(i in expToUp){ for (i in expToUp) {
if (character.exp >= expToUp[character.level]) { if (character.exp >= expToUp[character.level]) {
character.exp -= expToUp[character.level] character.exp -= expToUp[character.level]
character.level += 1 character.level += 1
character.firePoints += 1 character.firePoints += 1
await character.save() await character.save()
await ctx.sendMessage(`⤴️ Уровень вашего персонажа повысился до ${character.level}!`)} await ctx.sendMessage(`⤴️ Уровень вашего персонажа повысился до ${character.level}!`)
} }
}
} }
// Периодическое выполнение задач // Периодическое выполнение задач
function startRecoveryIntervals() { function startRecoveryIntervals() {
const interval = 60000; // 1 мин Интервал в миллисекундах (например, 1 минута) const interval = 60000; // 1 мин Интервал в миллисекундах (например, 1 минута)
setInterval(recoverHealth, interval); setInterval(recoverHealth, interval);
setInterval(recoverStamina, interval); setInterval(recoverStamina, interval);
} }
// Планируем выполнение задачи каждый день в 12 ночи // Планируем выполнение задачи каждый день в 12 ночи
@ -1781,10 +1783,10 @@ rpg.action(/attack_\d+/, async (ctx) => {
// Сообщение с информацией // Сообщение с информацией
await ctx.editMessageText( await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` + `⚔️ Сражение с ${enemy.name}\n\n` +
`❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` + `❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` +
`⚔️ Урон врага: ${enemy.damage}\n\n` + `⚔️ Урон врага: ${enemy.damage}\n\n` +
`📜 Логи битвы:\n${logMessage || "Пока ничего не произошло."}\n\n` + `📜 Логи битвы:\n${logMessage || "Пока ничего не произошло."}\n\n` +
`🎯 Выберите цель для атаки:`, `🎯 Выберите цель для атаки:`,
keyboard keyboard
); );
}); });
@ -1833,10 +1835,10 @@ rpg.action(/hit_\d+/, async (ctx) => {
await ctx.editMessageText( await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` + `⚔️ Сражение с ${enemy.name}\n\n` +
`❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` + `❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` +
`⚔️ Урон врага: ${enemy.damage}\n\n` + `⚔️ Урон врага: ${enemy.damage}\n\n` +
`📜 Логи битвы:\n${logs || "Пока ничего не произошло."}\n\n` + `📜 Логи битвы:\n${logs || "Пока ничего не произошло."}\n\n` +
`🎯 Выберите цель для атаки:`, `🎯 Выберите цель для атаки:`,
keyboard keyboard
); );
}); });
@ -1930,10 +1932,10 @@ rpg.action(/critical_\d+/, async (ctx) => {
await ctx.editMessageText( await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` + `⚔️ Сражение с ${enemy.name}\n\n` +
`❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` + `❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` +
`⚔️ Урон врага: ${enemy.damage}\n\n` + `⚔️ Урон врага: ${enemy.damage}\n\n` +
`📜 Логи битвы:\n${logs || "Пока ничего не произошло."}\n\n` + `📜 Логи битвы:\n${logs || "Пока ничего не произошло."}\n\n` +
`🎯 Выберите цель для атаки:`, `🎯 Выберите цель для атаки:`,
keyboard keyboard
); );
}); });
@ -1972,10 +1974,10 @@ rpg.action(/miss_\d+/, async (ctx) => {
await ctx.editMessageText( await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` + `⚔️ Сражение с ${enemy.name}\n\n` +
`❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` + `❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` +
`⚔️ Урон врага: ${enemy.damage}\n\n` + `⚔️ Урон врага: ${enemy.damage}\n\n` +
`📜 Логи битвы:\n${logs || "Пока ничего не произошло."}\n\n` + `📜 Логи битвы:\n${logs || "Пока ничего не произошло."}\n\n` +
`🎯 Выберите цель для атаки:`, `🎯 Выберите цель для атаки:`,
keyboard keyboard
); );
}); });