From 7248e5a45ceeb36a20d4a413d1405f56a4fcd063 Mon Sep 17 00:00:00 2001 From: Degradin <42292046+Degradin@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:01:54 +0300 Subject: [PATCH] v5.0-Crimes --- bot.js | 116 +++---- commands/menu.js | 13 +- config/imports.js | 2 +- config/index.js | 1 + crime.js | 70 +++++ handlers/createCharacters.js | 34 +++ models/character.model.js | 82 +++++ rpg.js | 567 +++++++++++++++++++++++++++++++++++ scenes/crime.js | 1 + scenes/pocketsteal.js | 97 +++--- scenes/shop.js | 172 +++-------- 11 files changed, 932 insertions(+), 223 deletions(-) create mode 100644 crime.js create mode 100644 handlers/createCharacters.js create mode 100644 models/character.model.js create mode 100644 rpg.js diff --git a/bot.js b/bot.js index 3f2068d..6b079e5 100644 --- a/bot.js +++ b/bot.js @@ -25,6 +25,7 @@ const { DailyModel } = global.config const bot = new Telegraf(process.env.BOT_TOKEN) + const rpg = require('./rpg'); // Подключение RPG-механик const crime = require('./scenes/crime') const pocketsteal = require('./scenes/pocketsteal') const shop = require('./scenes/shop') @@ -76,6 +77,7 @@ bot.telegram.setMyCommands([{ ]) bot.use(stage.middleware()) +bot.use(rpg) bot.use( session({ @@ -213,8 +215,7 @@ bot.command('start', async (ctx) => { }) bot.hears('Криминал', async (ctx) => { - await ctx.reply(`Closed`) - /*await ctx.scene.enter('Crime')*/ + await ctx.scene.enter('Crime') }) @@ -467,27 +468,10 @@ bot.hears('🏗️ Предприятия', async (ctx) => { console.error('Ошибка: пользователь не найден'); return await ctx.reply('Ошибка: пользователь не найден.'); } - - console.log('ID пользователя:', user.telegram_id); - const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } }); - - if (!warehouse) { - console.log('Склад не найден для пользователя:', user.telegram_id); - } else { - console.log('Найден склад:', warehouse); - } - const enterprises = await EnterpriseModel.findAll({ where: { playerId: user.telegram_id } }); - - if (!enterprises.length) { - console.log('Предприятия не найдены для пользователя:', user.telegram_id); - } else { - console.log('Количество предприятий:', enterprises.length); - } - let message = `🏗️ Меню предприятий:\n`; message += `У вас: ${enterprises.length} предприятий.\n`; message += warehouse @@ -995,42 +979,6 @@ bot.command('sellres', async (ctx) => { ); }); - -const recoverResourcePrices = async () => { - const resources = await ResourcePriceModel.findAll(); - - for (const resource of resources) { - // Определяем случайное колебание в диапазоне [-maxFluctuation, maxFluctuation] - const maxFluctuation = resource.basePrice * 0.3; // 30% от базовой цены - const priceFluctuation = (Math.random() * 2 - 1) * maxFluctuation; - - // Применяем колебание - resource.price = Math.round(resource.price + priceFluctuation); - - // Если цена выше базовой, шанс на её снижение - if (resource.price > resource.basePrice) { - const chanceToDrop = 0.5; // 50% шанс на снижение - if (Math.random() < chanceToDrop) { - resource.price -= Math.round(resource.basePrice * 0.01); // Снижение на 1% базовой цены - } - } - - // Если цена ниже базовой, восстанавливаем с учётом recoveryRate - if (resource.price < resource.basePrice) { - resource.price = Math.min( - Math.round(resource.price + resource.basePrice * resource.recoveryRate), - resource.basePrice // Не превышать базовую цену - ); - } - - // Гарантируем, что цена остаётся в диапазоне [50% basePrice, 150% basePrice] - resource.price = Math.max(resource.price, Math.round(resource.basePrice * 0.5)); // Минимум - resource.price = Math.min(resource.price, Math.round(resource.basePrice * 3)); // Максимум - - await resource.save(); // Сохраняем после всех корректировок - } -}; - bot.action(/sell_all_(\d+)/, async (ctx) => { const enterpriseId = ctx.match[1]; const enterprise = await EnterpriseModel.findByPk(enterpriseId); @@ -1211,6 +1159,45 @@ async function initializePrices() { initializePrices(); +const recoverResourcePrices = async () => { + const resources = await ResourcePriceModel.findAll(); + + for (const resource of resources) { + // Определяем случайное колебание в диапазоне [-maxFluctuation, maxFluctuation] + const maxFluctuation = resource.basePrice * 0.3; // 30% от базовой цены + const priceFluctuation = (Math.random() * 2 - 1) * maxFluctuation; + + // Применяем колебание + resource.price = Math.round(resource.price + priceFluctuation); + + // Если цена выше базовой, шанс на её снижение + if (resource.price > resource.basePrice) { + const chanceToDrop = 0.5; // 50% шанс на снижение + if (Math.random() < chanceToDrop) { + resource.price -= Math.round(resource.basePrice * 0.1); // Снижение на 1% базовой цены + } + } + + // Если цена ниже базовой, восстанавливаем с учётом recoveryRate + if (resource.price < resource.basePrice) { + resource.price = Math.min( + Math.round(resource.price + resource.basePrice * resource.recoveryRate), + resource.basePrice // Не превышать базовую цену + ); + } + + if (resource.price > resource.basePrice * 2.1) { + resource.price = Math.round(resource.basePrice * 0.79764918); // Устанавливаем цену на уровне 1.5 базовой + } + + // Гарантируем, что цена остаётся в диапазоне [50% basePrice, 150% basePrice] + resource.price = Math.max(resource.price, Math.round(resource.basePrice * 0.5)); // Минимум + resource.price = Math.min(resource.price, Math.round(resource.basePrice * 3)); // Максимум + + await resource.save(); // Сохраняем после всех корректировок + } +}; + // Функция добычи ресурсов const resourceProduction = async () => { try { @@ -1392,6 +1379,21 @@ const updateResourcePricesMessage = async () => { } }; +const resetCasinoFlag = async () => { + try { + await UserModel.update( + { isPlayingCasino: false }, // Новое значение для поля + { where: { isPlayingCasino: true } } // Только для тех, у кого флаг был установлен + ); + console.log('Флаг isPlayingCasino успешно сброшен для всех пользователей.'); + } catch (error) { + console.error('Ошибка при сбросе флага isPlayingCasino:', error); + } +}; + +// Вызов функции при запуске бота +resetCasinoFlag(); + // Запускаем функцию updateResourcePricesMessage(); // Запускаем процесс восстановления цен каждые 15 минут @@ -1521,7 +1523,9 @@ bot.action(/slots\d+/, async (ctx) => { if (!user || user.money < bet) { return ctx.answerCbQuery('💸 У вас недостаточно средств для ставки.', { show_alert: true }); } - + if (user.isPlayingCasino) { + return ctx.answerCbQuery('📛 Спам атака предотвращена.', { show_alert: true }); + } const timer = user.slottime; const cooldown = utils.setCooldown(user, 10, timer); if (user.slottime > cooldown.currentTime) { diff --git a/commands/menu.js b/commands/menu.js index c6d23fd..e87d0af 100644 --- a/commands/menu.js +++ b/commands/menu.js @@ -1,15 +1,26 @@ const { Markup } = require('telegraf') +const { + UserModel, + BusinessModel +} = global.config module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + const buttons = [] + if (user.status == 'admin') { + buttons.push("CampFireGG.Crime"); + } + return await ctx.reply('Main Menu', Markup .keyboard([ ['😎 Профиль'], // Row1 with 2 buttons ['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], // Row2 with 2 buttons ['🏗️ Предприятия'], ['📦 Контейнеры'], - ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'] // Row3 with 3 buttons + ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'], + buttons // Row3 with 3 buttons ]) .resize() ) diff --git a/config/imports.js b/config/imports.js index 4c4c7dd..fc67021 100644 --- a/config/imports.js +++ b/config/imports.js @@ -42,7 +42,7 @@ module.exports = [ ReportModel, BlockModel, PromocodeModel, - AFKPropertyModel + AFKPropertyModel, mainChat, adminList, expToUp, diff --git a/config/index.js b/config/index.js index de9e8b0..f3654b7 100644 --- a/config/index.js +++ b/config/index.js @@ -9,6 +9,7 @@ module.exports = { weapons : require('../presets/weapons.json'), equipment : require('../presets/equipment.json'), UserModel : require('../models/user.model'), + CharacterModel : require('../models/character.model'), WorldModel : require('../models/world.model'), JobModel : require('../models/job.model'), PropertyModel : require('../models/property.model'), diff --git a/crime.js b/crime.js new file mode 100644 index 0000000..b216052 --- /dev/null +++ b/crime.js @@ -0,0 +1,70 @@ +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.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.fire} +🧠 Интеллект (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('📦 Открыть инвентарь', 'open_inventory')], + [Markup.button.callback('🛠 Улучшить параметры', 'upgrade_stats')] + ])); +}); + +// Экспорт всех команд RPG +module.exports = rpg; diff --git a/handlers/createCharacters.js b/handlers/createCharacters.js new file mode 100644 index 0000000..cca0d29 --- /dev/null +++ b/handlers/createCharacters.js @@ -0,0 +1,34 @@ +const createCharactersForUsers = async () => { + try { + // Получаем всех пользователей из таблицы users + const users = await UserModel.findAll(); + + // Перебираем пользователей и создаём для каждого персонажа + for (const user of users) { + const existingCharacter = await CharacterModel.findOne({ where: { telegram_id: user.telegram_id } }); + + if (!existingCharacter) { + await CharacterModel.create({ + telegram_id: user.telegram_id, + username: user.username, + name: user.username || 'Безымянный герой', + dirtymoney: user.dirtymoney || 0, + stealedcards: user.stealedcards || 0, + shoprobcd: user.shoprobcd || 0, + pocketstealcd: user.pocketstealcd || 0, + }); + + console.log(`Персонаж создан для пользователя: ${user.username} (${user.telegram_id})`); + } else { + console.log(`Персонаж уже существует для пользователя: ${user.username} (${user.telegram_id})`); + } + } + + console.log('Создание персонажей завершено.'); + } catch (error) { + console.error('Ошибка при создании персонажей:', error); + } +}; + +// Запуск функции +createCharactersForUsers(); \ No newline at end of file diff --git a/models/character.model.js b/models/character.model.js new file mode 100644 index 0000000..0de23b7 --- /dev/null +++ b/models/character.model.js @@ -0,0 +1,82 @@ +const sequelize = require('../db'); +const { DataTypes } = require('sequelize'); + +const Character = sequelize.define('character', { + telegram_id: { + type: DataTypes.BIGINT, + primaryKey: true, + unique: true + }, + username: { + type: DataTypes.STRING + }, + name: { + type: DataTypes.STRING + }, + level: { + type: DataTypes.INTEGER, + defaultValue: 1 + }, + exp: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, + hp: { + type: DataTypes.INTEGER, + defaultValue: 100 + }, // Текущее здоровье + max_hp: { + type: DataTypes.INTEGER, + defaultValue: 100 + }, // Максимальное здоровье + armor: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, // Броня для уменьшения урона + stamina: { + type: DataTypes.INTEGER, + defaultValue: 100 + }, // Текущая выносливость + max_stamina: { + type: DataTypes.INTEGER, + defaultValue: 100 + }, // Максимальная выносливость + force: { + type: DataTypes.INTEGER, + defaultValue: 1 + }, // "F": физическая сила, влияет на урон + intelligence: { + type: DataTypes.INTEGER, + defaultValue: 1 + }, // "I": интеллект для исследований/крафта + resilience: { + type: DataTypes.INTEGER, + defaultValue: 1 + }, // "R": устойчивость, влияет на здоровье и защиту + endurance: { + type: DataTypes.INTEGER, + defaultValue: 1 + }, // "E": выносливость, влияет на количество выполняемых заданий + dirtymoney: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, // Грязные деньги, заработанные нелегально + stealedcards: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, // Украденные карточки + shoprobcd: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, // КД на ограбление магазина + pocketstealcd: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, // КД на кражу из кармана + inventory: { + type: DataTypes.JSON, + defaultValue: [] + }, // Инвентарь, где будут храниться предметы +}); + +module.exports = Character; diff --git a/rpg.js b/rpg.js new file mode 100644 index 0000000..e00321a --- /dev/null +++ b/rpg.js @@ -0,0 +1,567 @@ +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 { + 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 { + 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 { + 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; diff --git a/scenes/crime.js b/scenes/crime.js index 7f84004..bb4763c 100644 --- a/scenes/crime.js +++ b/scenes/crime.js @@ -23,6 +23,7 @@ const { const crime = new Scenes.BaseScene('Crime'); crime.enter( async (ctx) => { + if(ctx.from.id != 275416286) ctx.reply('WIP') ctx.reply('Scene: Выберите ограбление', Markup.inlineKeyboard([ [{text: 'Карманные кражи [7 lvl.][SOLO]', callback_data: `POCKET_ACTION`}], [{text: 'Магазин [8 lvl.][SOLO/DUO]', callback_data: `SHOP_ACTION`}], diff --git a/scenes/pocketsteal.js b/scenes/pocketsteal.js index aec5b8e..b8e4bcc 100644 --- a/scenes/pocketsteal.js +++ b/scenes/pocketsteal.js @@ -8,6 +8,7 @@ const { slots, phones, UserModel, +CharacterModel, WorldModel, SkillsModel, PropertyModel @@ -49,32 +50,49 @@ steal.action(`POCKET_TARGET`, async (ctx) => { }); steal.action(`MONEY_IN_POCKET`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level - if(chance < 20) return ctx.editMessageText('Вы были замечены во время кражи.'); - let moneyIn = rand(5, 1000) - user.dirtymoney += moneyIn - user.save() - return ctx.editMessageText(`Вы успешно украли Ð${spaces(moneyIn)} из кармана.`) + // Получаем пользователя и его персонажа + //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 = rand(0, 100); // Случайное число от 0 до 100 + if (randomRoll > chance) { + return ctx.editMessageText('Вы были замечены во время кражи.'); + } + + // Успешная кража + let moneyIn = rand(5, 1000); + character.dirtymoney += moneyIn; + await character.save(); + + return ctx.editMessageText(`Вы успешно украли Ð${spaces(moneyIn)} из кармана.`); }); + steal.action(`PHONE`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) + 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 skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level - if(chance < 60) return ctx.editMessageText('Вы были замечены во время кражи.'); + // Расчёт шанса на успешную кражу + let baseChance = 20; // Базовый шанс + let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". + let randomRoll = rand(0, 100); // Случайное число от 0 до 100 + if(chance < randomRoll) return ctx.editMessageText('Вы были замечены во время кражи.'); let randPhone = rand(1,10) if (property.mobile.name) { let dirtyMoney = Math.round(phones[randPhone].price/100*70) - user.dirtymoney += dirtyMoney + character.dirtymoney += dirtyMoney return await ctx.reply(`Вы сбыли украденный ${phones[randPhone].name} за Ð${dirtyMoney}`) } property.mobile = phones[randPhone] - await user.save() + await character.save() await property.save() return ctx.editMessageText(`Вы успешно украли ${phones[randPhone].name} из кармана.`) }); @@ -89,35 +107,38 @@ steal.action(`POCKET_WALLET`, async (ctx) => { }); steal.action(`MONEY_IN_WALLET`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level - if(chance < 40) return ctx.editMessageText('Вы были замечены во время кражи.'); + //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 = rand(0, 100); // Случайное число от 0 до 100 + if(chance < randomRoll) return ctx.editMessageText('Вы были замечены во время кражи.'); let moneyIn = rand(1000, 10000) - user.dirtymoney += moneyIn - user.save() + character.dirtymoney += moneyIn + character.save() return ctx.editMessageText(`Вы успешно украли Ð${spaces(moneyIn)} из бумажника.`) }); steal.action(`CARD_IN_WALLET`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level - if(chance < 50) return ctx.editMessageText('Вы были замечены во время кражи.'); - user.stealedcards += 1 - user.save() + //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 = rand(0, 100); // Случайное число от 0 до 100 + if(chance < randomRoll) return ctx.editMessageText('Вы были замечены во время кражи.'); + character.stealedcards += 1 + character.save() return ctx.editMessageText(`Вы успешно украли 💳 из бумажника.`) }); steal.action(`POCKET_BAG`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level - console.log(chance) - if(chance < 60) return ctx.editMessageText('Вы были замечены во время кражи.'); + //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 = rand(0, 100); // Случайное число от 0 до 100 + if(chance < randomRoll) return ctx.editMessageText('Вы были замечены во время кражи.'); let times = rand(2,20) let moneyIn = 0 let text = `` @@ -143,8 +164,8 @@ steal.action(`POCKET_BAG`, async (ctx) => { break; } } - user.dirtymoney += moneyIn - user.save() + character.dirtymoney += moneyIn + character.save() return ctx.editMessageText(`Вы успешно украли сумку и сбыли все ценности из нее:\n${text}\nОбщий куш: Ð${spaces(moneyIn)}`) }); diff --git a/scenes/shop.js b/scenes/shop.js index 126a6cd..93e710f 100644 --- a/scenes/shop.js +++ b/scenes/shop.js @@ -8,6 +8,7 @@ const { slots, phones, UserModel, +CharacterModel, WorldModel, SkillsModel, PropertyModel @@ -37,76 +38,18 @@ shop.enter(async (ctx) => { if (user.shoprobcd > cooldown.currentTime) return ctx.editMessageText(`📛 Данное действие будет доступно через ${cooldown.timeLeftInMinutes} мин.`); user.shoprobcd = cooldown.endTime user.save() - ctx.editMessageText('Выберите режим', Markup.inlineKeyboard([ - [ - {text: 'SOLO', callback_data: `SHOP_SOLO`}, - {text: 'DUO', callback_data: `SHOP_DUO`}, - {text: 'GROUP', callback_data: `SHOP_GROUP`}, - {text: 'ADMIN', callback_data: `SHOP_ADMIN`} - ] -]).resize()) -}); - -shop.action(`SHOP_DUO`, async (ctx) => { - ctx.reply(`Еще не доступно.`) -}); - -shop.action(`SHOP_GROUP`, async (ctx) => { - ctx.reply(`Еще не доступно.`) -}); - - - -shop.action(`DEBUG_PVE`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let skill = await SkillsModel.findByPk(ctx.from.id) - ctx.session.enemy = { - name: 'Полицейский', - hp: 100, - armor: 100 - } - return ctx.scene.enter('NEWPVE') -}); - - - -shop.action(`SHOP_ADMIN`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - if(user.status != 'admin') return ctx.editMessageText(`Написано же ADMIN блять.`) - return ctx.editMessageText('Admin Panel', Markup.inlineKeyboard([ - [{text: 'New PVE', callback_data: `DEBUG_PVE`}], - [{text: 'Убить охранника [Владение оружием]', callback_data: `SHOP_GUARD_KILL`}] -])) -}); - -shop.action(`SHOP_SOLO`, async (ctx) => { - let property = await PropertyModel.findByPk(ctx.from.id); - if(property.equipment != 0){ - ctx.session.user = { - hp: 100, - armor: property.equipment.armor - } - }else{ - ctx.session.user = { - hp: 100, - armor: 0 - } - } - - ctx.editMessageText('Стадии:', Markup.inlineKeyboard([ - [ - {text: 'Вход', callback_data: `SHOP_ENTER`}, - //{text: 'Охранник [DEV]', callback_data: `SHOP_ENTER`}, - //{text: 'Отчет', callback_data: `SHOP_CASH_BREAK_SUCCESS`} - ] + return ctx.editMessageText('Стадии:', Markup.inlineKeyboard([ + [{text: 'Взлом кассы', callback_data: `SHOP_CASH_BREAK`}], + [{text: 'Разбить кассу', callback_data: `SHOP_CASH_SMASH`}] ])) }); shop.action(`SHOP_ENTER`, async (ctx) => { - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level - if(chance < 70) { + let character = await CharacterModel.findByPk(ctx.from.id); + let baseChance = 20; // Базовый шанс + let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". + let randomRoll = rand(0, 100); // Случайное число от 0 до 100 + if(chance < randomRoll) { return ctx.editMessageText('Вы заметили охранника, с ним нужно что-то сделать...', Markup.inlineKeyboard([ [{text: 'Избавиться от охранника [Скрытность]', callback_data: `SHOP_GUARD_STEALTH`}], [{text: 'Убить охранника [Владение оружием]', callback_data: `SHOP_GUARD_KILL`}] @@ -120,9 +63,6 @@ shop.action(`SHOP_ENTER`, async (ctx) => { }); shop.action(`SHOP_GUARD`, async (ctx) => { - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level return ctx.editMessageText('Стадии:', Markup.inlineKeyboard([ [{text: 'Избавиться от охранника [Скрытность]', callback_data: `SHOP_GUARD_STEALTH`}], [{text: 'Убить охранника [Владение оружием]', callback_data: `SHOP_GUARD_KILL`}] @@ -130,18 +70,12 @@ shop.action(`SHOP_GUARD`, async (ctx) => { }); shop.action(`SHOP_GUARD_STEALTH`, async (ctx) => { - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level - if(chance < 40) { - ctx.session.stage = 'SHOP_GUARD_STEALTH' - ctx.reply(`Нападение!`) - ctx.session.enemy = { - name: 'Охранник', - hp: 100, - armor: 20 - } - return ctx.scene.enter('PVE') + let character = await CharacterModel.findByPk(ctx.from.id); + let baseChance = 20; // Базовый шанс + let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". + let randomRoll = rand(0, 100); // Случайное число от 0 до 100 + if(chance < randomRoll) { //Скрытно не удалось, столкновение + } return ctx.editMessageText('Охранник обезврежен, вы подходите к кассиру:', Markup.inlineKeyboard([ [{text: 'Убить кассира и забрать все из кассы', callback_data: `SHOP_KILL_CASHIER`}], @@ -151,9 +85,10 @@ shop.action(`SHOP_GUARD_STEALTH`, async (ctx) => { }); shop.action(`SHOP_GUARD_KILL`, async (ctx) => { - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level + let character = await CharacterModel.findByPk(ctx.from.id); + let baseChance = 20; // Базовый шанс + let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". + let randomRoll = rand(0, 100); // Случайное число от 0 до 100 if(chance > 10) { ctx.session.stage = 'SHOP_GUARD_KILL' ctx.session.enemy = { @@ -171,9 +106,10 @@ shop.action(`SHOP_GUARD_KILL`, async (ctx) => { }); shop.action(`SHOP_KILL_CASHIER`, async (ctx) => { - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.stealing.level + let character = await CharacterModel.findByPk(ctx.from.id); + let baseChance = 20; // Базовый шанс + let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". + let randomRoll = rand(0, 100); // Случайное число от 0 до 100 if(chance < 60 && !ctx.session.enemy) { ctx.session.stage = 'SHOP_KILL_CASHIER' ctx.editMessageText('Вы заметили охранника, с ним нужно что-то сделать...'); @@ -191,16 +127,16 @@ shop.action(`SHOP_KILL_CASHIER`, async (ctx) => { }); shop.action(`SHOP_CASH_BREAK`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) - chance += skill.lockpick.level + let character = await CharacterModel.findByPk(ctx.from.id); + let baseChance = 20; // Базовый шанс + let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". + let randomRoll = rand(0, 100); // Случайное число от 0 до 100 let cashIn = rand(1000, 10000) let timer = 1000 - if(chance < 99) { + if(chance < randomRoll) { const keyboard = generateKeyboard(); ctx.deleteMessage() - return ctx.reply('Взлом замка:', keyboard); + return ctx.reply('Касса закрыта, вы начали взлом замка:', keyboard); //ctx.editMessageText('Вы начали взлом кассы.'); //return ctx.scene.enter('LOCKPICK') } @@ -212,8 +148,8 @@ shop.action(`SHOP_CASH_BREAK`, async (ctx) => { timer += 500 } setTimeout(() => { -user.dirtymoney += cashIn -user.save() + character.dirtymoney += cashIn + character.save() return ctx.editMessageText(`Вы достали из кассы Ð${cashIn}, пора валить.`, Markup.inlineKeyboard([ [{text: 'Завершить ограбление', callback_data: `SHOP_END`}] ])) @@ -221,44 +157,27 @@ return ctx.editMessageText(`Вы достали из кассы Ð${cashIn}, п }); shop.action(`SHOP_CASH_SMASH`, async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let skill = await SkillsModel.findByPk(ctx.from.id) - let chance = rand(0, 100) + let character = await CharacterModel.findByPk(ctx.from.id); + let baseChance = 20; // Базовый шанс + let chance = baseChance + character.intelligence * 2; // Увеличиваем шанс на 2% за каждый пункт "Разума". + let randomRoll = rand(0, 100); // Случайное число от 0 до 100 let cashIn = rand(1000, 10000) let timer = 1000 - if(chance < 50) { - ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация.') - ctx.session.stage = 'SHOP_CASH_SMASH' - ctx.session.enemy = { - name: 'Полицейский', - hp: 100, - armor: 100 - } - for(i=0; i { - cashIn += rand(1000, 10000) - ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${cashIn}`) - }, timer) - timer += 500 - } - setTimeout(() => { - user.dirtymoney += cashIn - user.save() - return ctx.editMessageText(`Вы достали из кассы Ð${cashIn}, пора валить.`) - }, timer+300) - return ctx.scene.enter('PVE') + if(chance < randomRoll) { + return ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация. Вы сбежали.') } + ctx.editMessageText('Вы разбили кассовый аппарат, и сработала сигнализация.') for(i=0; i { - cashIn += rand(1000, 10000) - ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${cashIn}`) + cashIn += rand(500, 5000) + ctx.editMessageText(`⏏️ Вы в спешке достали из кассы: Ð${cashIn}`) }, timer) timer += 500 } setTimeout(() => { -user.dirtymoney += cashIn -user.save() -return ctx.editMessageText(`Вы достали из кассы Ð${cashIn}, пора валить.`, Markup.inlineKeyboard([ + character.dirtymoney += cashIn + character.save() +return ctx.editMessageText(`Вы в спешке достали из кассы Ð${cashIn}, пора валить.`, Markup.inlineKeyboard([ [{text: 'Завершить ограбление', callback_data: `SHOP_END`}] ])) }, timer+300) @@ -270,7 +189,7 @@ shop.action(`SHOP_CASH_BREAK_SUCCESS`, async (ctx) => { let timer = 100 for(i=0; i { - cashIn += rand(1000, 10000) + cashIn += rand(3000, 10000) ctx.editMessageText(`⏏️ Вы достали из кассы: Ð${cashIn}`) }, timer) timer += 500 @@ -285,8 +204,7 @@ shop.action(`SHOP_CASH_BREAK_SUCCESS`, async (ctx) => { }); shop.action(`SHOP_END`, async (ctx) => { - ctx.editMessageText('Ограбление завершено!') - return ctx.scene.leave(); + return ctx.editMessageText('Ограбление завершено!') }); shop.action(/lock_*/, (ctx) => {