v5.2-rc
Crime update
This commit is contained in:
parent
4f97a3dba1
commit
125b782a64
7
bot.js
7
bot.js
@ -206,10 +206,11 @@ bot.command('start', async (ctx) => {
|
|||||||
return await ctx.reply('Главное меню', Markup
|
return await ctx.reply('Главное меню', Markup
|
||||||
.keyboard([
|
.keyboard([
|
||||||
['😎 Профиль'], // Row1 with 2 buttons
|
['😎 Профиль'], // Row1 with 2 buttons
|
||||||
['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], // Row2 with 2 buttons
|
['🗄️ Работать', '🌐 Организация', '🏗️ Предприятия', '🏯 Казино'], // Row2 with 2 buttons
|
||||||
['🏗️ Предприятия'],
|
['CampFireGG.Crime'],
|
||||||
|
['🎁 Бонус'],
|
||||||
['📦 Контейнеры'],
|
['📦 Контейнеры'],
|
||||||
['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'] // Row3 with 3 buttons
|
['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'],
|
||||||
])
|
])
|
||||||
.resize()
|
.resize()
|
||||||
)
|
)
|
||||||
|
@ -10,14 +10,14 @@ module.exports = async (ctx) => {
|
|||||||
let user = await UserModel.findByPk(ctx.from.id)
|
let user = await UserModel.findByPk(ctx.from.id)
|
||||||
const buttons = []
|
const buttons = []
|
||||||
if (user.status == 'admin') {
|
if (user.status == 'admin') {
|
||||||
buttons.push("CampFireGG.Crime");
|
buttons.push("Топ");
|
||||||
}
|
}
|
||||||
|
|
||||||
return await ctx.reply('Main Menu', Markup
|
return await ctx.reply('Main Menu', Markup
|
||||||
.keyboard([
|
.keyboard([
|
||||||
['😎 Профиль'], // Row1 with 2 buttons
|
['😎 Профиль'], // Row1 with 2 buttons
|
||||||
['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], // Row2 with 2 buttons
|
['🗄️ Работать', '🌐 Организация', '🏗️ Предприятия', '🏯 Казино'], // Row2 with 2 buttons
|
||||||
['🏗️ Предприятия'],
|
['CampFireGG.Crime'],
|
||||||
|
['🎁 Бонус'],
|
||||||
['📦 Контейнеры'],
|
['📦 Контейнеры'],
|
||||||
['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'],
|
['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'],
|
||||||
buttons // Row3 with 3 buttons
|
buttons // Row3 with 3 buttons
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
const sequelize = require('../db');
|
||||||
|
const Character = require('../models/character.model');
|
||||||
|
const Inventory = require('../models/inventory.model');
|
||||||
|
// Устанавливаем ассоциации здесь
|
||||||
|
Character.hasMany(Inventory, { foreignKey: 'telegram_id' });
|
||||||
|
Inventory.belongsTo(Character, { foreignKey: 'telegram_id' });
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
weaponshop : require('../json/weaponshop.json'),
|
weaponshop : require('../json/weaponshop.json'),
|
||||||
slots : require('../json/slots.json'),
|
slots : require('../json/slots.json'),
|
||||||
@ -10,6 +17,7 @@ module.exports = {
|
|||||||
equipment : require('../presets/equipment.json'),
|
equipment : require('../presets/equipment.json'),
|
||||||
UserModel : require('../models/user.model'),
|
UserModel : require('../models/user.model'),
|
||||||
CharacterModel : require('../models/character.model'),
|
CharacterModel : require('../models/character.model'),
|
||||||
|
InventoryModel : require('../models/inventory.model'),
|
||||||
ItemsModel : require('../models/items.model'),
|
ItemsModel : require('../models/items.model'),
|
||||||
StolenCardsModel : require('../models/stolencards.model'),
|
StolenCardsModel : require('../models/stolencards.model'),
|
||||||
WorldModel : require('../models/world.model'),
|
WorldModel : require('../models/world.model'),
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
const sequelize = require('../db');
|
|
||||||
const { DataTypes } = require('sequelize');
|
const { DataTypes } = require('sequelize');
|
||||||
|
const sequelize = require('../db');
|
||||||
|
|
||||||
const Character = sequelize.define('character', {
|
const Character = sequelize.define('character', {
|
||||||
telegram_id: {
|
telegram_id: {
|
||||||
type: DataTypes.BIGINT,
|
type: DataTypes.BIGINT,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
unique: true
|
unique: true,
|
||||||
},
|
},
|
||||||
username: {
|
username: {
|
||||||
type: DataTypes.STRING
|
type: DataTypes.STRING
|
||||||
|
@ -2,9 +2,17 @@ const { DataTypes } = require('sequelize');
|
|||||||
const sequelize = require('../db');
|
const sequelize = require('../db');
|
||||||
|
|
||||||
const Inventory = sequelize.define('inventory', {
|
const Inventory = sequelize.define('inventory', {
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true
|
||||||
|
},
|
||||||
telegram_id: {
|
telegram_id: {
|
||||||
type: DataTypes.BIGINT,
|
type: DataTypes.BIGINT, // Используем другой внешний ключ
|
||||||
primaryKey: true
|
references: {
|
||||||
|
model: 'characters', // Указываем правильное имя модели
|
||||||
|
key: 'telegram_id', // Внешний ключ указывает на telegram_id в модели Character
|
||||||
|
},
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
@ -34,8 +42,10 @@ const Inventory = sequelize.define('inventory', {
|
|||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: true
|
allowNull: true
|
||||||
}, // Длительность эффекта в секундах
|
}, // Длительность эффекта в секундах
|
||||||
|
equipped: {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
defaultValue: false
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = Inventory;
|
module.exports = Inventory;
|
||||||
|
370
rpg.js
370
rpg.js
@ -12,6 +12,7 @@ const {
|
|||||||
expToUp,
|
expToUp,
|
||||||
UserModel,
|
UserModel,
|
||||||
CharacterModel,
|
CharacterModel,
|
||||||
|
InventoryModel,
|
||||||
ItemsModel,
|
ItemsModel,
|
||||||
StolenCardsModel,
|
StolenCardsModel,
|
||||||
WorldModel,
|
WorldModel,
|
||||||
@ -28,6 +29,32 @@ const {
|
|||||||
} = global.config
|
} = global.config
|
||||||
const rpg = new Composer();
|
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;
|
||||||
|
|
||||||
|
const currentTime = utils.getCurrentTime();
|
||||||
|
|
||||||
|
switch (ctx.updateType) {
|
||||||
|
case 'message':
|
||||||
|
console.log(`${currentTime}: [RPG] ${username}: ${ctx.update.message.text}`);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'callback_query':
|
||||||
|
console.log(`${currentTime}: [RPG] ${username}: ${ctx.update.callback_query.data}`);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'edited_message':
|
||||||
|
console.log(`${currentTime}: [RPG] ${username} edited: ${ctx.update.edited_message.text}`);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log(`${currentTime}: [RPG] Unknown update type:`, ctx.update);
|
||||||
|
}
|
||||||
|
|
||||||
|
await next(); // Передаем управление следующему middleware
|
||||||
|
});
|
||||||
|
|
||||||
rpg.hears('RPG', async (ctx) => {
|
rpg.hears('RPG', async (ctx) => {
|
||||||
let message = `Меню:\n`;
|
let message = `Меню:\n`;
|
||||||
@ -61,7 +88,7 @@ rpg.action('rpg_profile', async (ctx) => {
|
|||||||
🔋 Выносливость (E): ${character.endurance}
|
🔋 Выносливость (E): ${character.endurance}
|
||||||
🔥 Стамина: ${character.stamina}/${character.max_stamina}
|
🔥 Стамина: ${character.stamina}/${character.max_stamina}
|
||||||
💰 Грязные деньги: ${utils.spaces(character.dirtymoney)}
|
💰 Грязные деньги: ${utils.spaces(character.dirtymoney)}
|
||||||
🃏 Карточки: ${stolenCards.length}
|
🃏 Карты: ${stolenCards.length}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Отправляем сообщение
|
// Отправляем сообщение
|
||||||
@ -144,8 +171,9 @@ rpg.hears('CampFireGG.Crime', async (ctx) => {
|
|||||||
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('💳 Карточки', 'view_cards')],
|
[Markup.button.callback('💳 Карточки', 'view_cards')],
|
||||||
[Markup.button.callback('💰 Инвентарь', 'inventory')],
|
[Markup.button.callback('🎒 Инвентарь', 'inventory')],
|
||||||
|
[Markup.button.callback('💰 Магазин', 'shop')],
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -294,7 +322,7 @@ rpg.action(/purchase_/, async (ctx) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Если баланс карты достаточно для покупки, добавляем предмет в инвентарь
|
// Если баланс карты достаточно для покупки, добавляем предмет в инвентарь
|
||||||
character.inventory.push(item.id);
|
character.InventoryModel.push(item.id);
|
||||||
await character.save();
|
await character.save();
|
||||||
|
|
||||||
// Если товар электронный, начисляем процент от стоимости на счет
|
// Если товар электронный, начисляем процент от стоимости на счет
|
||||||
@ -339,11 +367,21 @@ rpg.action(/purchase_fail_/, async (ctx) => {
|
|||||||
rpg.action(/brutecard_/, async (ctx) => {
|
rpg.action(/brutecard_/, async (ctx) => {
|
||||||
const cardId = ctx.match.input.split('_')[1]; // Получаем ID карточки из callback_data
|
const cardId = ctx.match.input.split('_')[1]; // Получаем ID карточки из callback_data
|
||||||
const card = await StolenCardsModel.findByPk(cardId); // Ищем карточку в базе данных
|
const card = await StolenCardsModel.findByPk(cardId); // Ищем карточку в базе данных
|
||||||
|
const inventory = await InventoryModel.findAll({ where: { telegram_id: ctx.from.id } }); // Загружаем предметы из инвентаря
|
||||||
|
|
||||||
if (!card) {
|
if (!card) {
|
||||||
return ctx.answerCbQuery('Карточка не найдена.');
|
return ctx.answerCbQuery('Карточка не найдена.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Проверяем наличие "Эмулятора картридера" в инвентаре
|
||||||
|
const emulator = inventory.find((item) => item.name === 'Эмулятор картридера');
|
||||||
|
if (!emulator) {
|
||||||
|
return ctx.reply('Для запуска брутфорса вам нужен "Эмулятор картридера".');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удаляем "Эмулятор картридера" из инвентаря
|
||||||
|
await InventoryModel.destroy({ where: { id: emulator.id } });
|
||||||
|
|
||||||
const buttonsCount = 10; // Количество кнопок
|
const buttonsCount = 10; // Количество кнопок
|
||||||
const winButton = utils.rand(1, buttonsCount); // Выбираем случайную кнопку для успешного пина
|
const winButton = utils.rand(1, buttonsCount); // Выбираем случайную кнопку для успешного пина
|
||||||
const maxAttempts = 3; // Максимальное количество попыток
|
const maxAttempts = 3; // Максимальное количество попыток
|
||||||
@ -378,11 +416,25 @@ rpg.action(/brutecard_/, async (ctx) => {
|
|||||||
|
|
||||||
// Отправляем сообщение с клавиатурой
|
// Отправляем сообщение с клавиатурой
|
||||||
await ctx.reply(
|
await ctx.reply(
|
||||||
`💳 Брутфорс карты\n\nПопробуйте подобрать правильный ПИН-код. У вас есть ${maxAttempts - attempts[ctx.from.id]} попыток.`,
|
`💳 Брутфорс карты\n
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
${card.bankName.toUpperCase()}
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
Номер: ${card.cardNumber}
|
||||||
|
CVV: ${card.cvv}
|
||||||
|
Владелец: ${card.holderName.toUpperCase()}
|
||||||
|
Срок действия: ${card.expiresDate}
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
|
||||||
|
Попробуйте подобрать правильный ПИН-код. У вас есть ${maxAttempts - attempts[ctx.from.id]} попыток.
|
||||||
|
|
||||||
|
"Эмулятор картридера" был использован.`,
|
||||||
keyboard
|
keyboard
|
||||||
);
|
);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Обработка неудачной попытки взлома
|
// Обработка неудачной попытки взлома
|
||||||
rpg.action(/brute_fail_/, async (ctx) => {
|
rpg.action(/brute_fail_/, async (ctx) => {
|
||||||
const cardId = ctx.match.input.split('_')[2];
|
const cardId = ctx.match.input.split('_')[2];
|
||||||
@ -430,7 +482,17 @@ rpg.action(/brute_fail_/, async (ctx) => {
|
|||||||
|
|
||||||
// Обновляем сообщение с клавиатурой
|
// Обновляем сообщение с клавиатурой
|
||||||
await ctx.editMessageText(
|
await ctx.editMessageText(
|
||||||
`💳 Взлом карточки\n\nПопробуйте подобрать правильный ПИН-код. У вас есть ${maxAttempts - attempts[ctx.from.id]} попыток.`,
|
`💳 Брутфорс карты\n
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
${card.bankName.toUpperCase()}
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
Номер: ${card.cardNumber}
|
||||||
|
CVV: ${card.cvv}
|
||||||
|
Владелец: ${card.holderName.toUpperCase()}
|
||||||
|
Срок действия: ${card.expiresDate}
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
|
||||||
|
Попробуйте подобрать правильный ПИН-код. У вас есть ${maxAttempts - attempts[ctx.from.id]} попыток.`,
|
||||||
keyboard
|
keyboard
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -458,7 +520,17 @@ rpg.action(/brute_success_/, async (ctx) => {
|
|||||||
|
|
||||||
// Отправляем сообщение о выигрыше
|
// Отправляем сообщение о выигрыше
|
||||||
await ctx.editMessageText(
|
await ctx.editMessageText(
|
||||||
`✅ Взлом успешен! Вы получили Ð${amount} грязных денег.`
|
`💳 Брутфорс карты\n
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
${card.bankName.toUpperCase()}
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
Номер: ${card.cardNumber}
|
||||||
|
CVV: ${card.cvv}
|
||||||
|
Владелец: ${card.holderName.toUpperCase()}
|
||||||
|
Срок действия: ${card.expiresDate}
|
||||||
|
━━━━━━━━━━━━━━━━━━━━
|
||||||
|
|
||||||
|
✅ Взлом успешен! Вы получили Ð${amount}.`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -799,56 +871,44 @@ rpg.action('inventory', async (ctx) => {
|
|||||||
return ctx.reply('Персонаж не найден!');
|
return ctx.reply('Персонаж не найден!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const inventory = character.inventory || [];
|
// Загружаем предметы из инвентаря
|
||||||
const equippedItems = character.equippedItems || [];
|
const inventory = await InventoryModel.findAll({ where: { telegram_id: ctx.from.id } });
|
||||||
|
|
||||||
// Если инвентарь пустой
|
if (inventory.length === 0) {
|
||||||
if (inventory.length === 0 && equippedItems.length === 0) {
|
|
||||||
return ctx.reply('Ваш инвентарь пуст.');
|
return ctx.reply('Ваш инвентарь пуст.');
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = '*Ваш инвентарь:*\n\n';
|
let message = '*Ваш инвентарь:*\n\n';
|
||||||
|
|
||||||
// Снаряженные предметы
|
// Группируем предметы по их состоянию (снаряженные/обычные)
|
||||||
|
const equippedItems = inventory.filter((item) => item.equipped);
|
||||||
|
const unequippedItems = inventory.filter((item) => !item.equipped);
|
||||||
|
|
||||||
if (equippedItems.length > 0) {
|
if (equippedItems.length > 0) {
|
||||||
message += '🛡️ *Снаряженные предметы:*\n';
|
message += '🛡️ *Снаряженные предметы:*\n';
|
||||||
for (const item of equippedItems) {
|
equippedItems.forEach((item) => {
|
||||||
if (item) {
|
|
||||||
message += `- ${item.name} (${item.type})\n`;
|
message += `- ${item.name} (${item.type})\n`;
|
||||||
}
|
});
|
||||||
}
|
|
||||||
message += '\n';
|
message += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Предметы в инвентаре
|
if (unequippedItems.length > 0) {
|
||||||
if (inventory.length > 0) {
|
|
||||||
message += '🎒 *Предметы в инвентаре:*\n';
|
message += '🎒 *Предметы в инвентаре:*\n';
|
||||||
for (const item of inventory) {
|
unequippedItems.forEach((item) => {
|
||||||
if (item) {
|
|
||||||
message += `- ${item.name} (${item.type})\n`;
|
message += `- ${item.name} (${item.type})\n`;
|
||||||
}
|
});
|
||||||
}
|
|
||||||
message += '\n';
|
message += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Кнопки для взаимодействия
|
// Кнопки для взаимодействия
|
||||||
const buttons = [];
|
const buttons = [
|
||||||
|
...unequippedItems.map((item) =>
|
||||||
for (const item of inventory) {
|
|
||||||
if (item) {
|
|
||||||
buttons.push(
|
|
||||||
Markup.button.callback(`🎯 Использовать ${item.name}`, `use_item_${item.id}`)
|
Markup.button.callback(`🎯 Использовать ${item.name}`, `use_item_${item.id}`)
|
||||||
);
|
),
|
||||||
}
|
...equippedItems.map((item) =>
|
||||||
}
|
Markup.button.callback(`🚫 Снять ${item.name}`, `unequip_item_${item.id}`)
|
||||||
|
),
|
||||||
for (const item of equippedItems) {
|
];
|
||||||
if (item) {
|
|
||||||
buttons.push(
|
|
||||||
Markup.button.callback(`🚫 Снять ${item.name}`, `use_item_${item.id}`)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await ctx.replyWithMarkdown(message, Markup.inlineKeyboard(buttons, { columns: 2 }));
|
await ctx.replyWithMarkdown(message, Markup.inlineKeyboard(buttons, { columns: 2 }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -857,66 +917,64 @@ rpg.action('inventory', async (ctx) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
rpg.action(/use_item_(\d+)/, async (ctx) => {
|
rpg.action(/use_item_(\d+)/, async (ctx) => {
|
||||||
const itemId = parseInt(ctx.match[1], 10);
|
const itemId = parseInt(ctx.match[1], 10);
|
||||||
const character = await CharacterModel.findByPk(ctx.from.id);
|
const item = await InventoryModel.findByPk(itemId);
|
||||||
const item = await ItemsModel.findByPk(itemId);
|
|
||||||
|
|
||||||
const inventory = character.inventory || [];
|
if (!item || item.telegram_id != ctx.from.id) {
|
||||||
const isEquipped = character.equippedItems.some((equippedItem) => equippedItem.id === itemId); // Проверяем, снаряжен ли предмет
|
return ctx.reply('Этот предмет не найден в вашем инвентаре.');
|
||||||
|
|
||||||
// Проверка наличия предмета в инвентаре
|
|
||||||
if (!inventory.some((invItem) => invItem.id === itemId) && !isEquipped) {
|
|
||||||
return ctx.reply('У вас нет этого предмета.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Если предмет уже снаряжен
|
|
||||||
if (isEquipped) {
|
|
||||||
// Снимаем предмет
|
|
||||||
const resultMessages = await character.removeEquippedItem(item); // Убираем предмет из снаряженных
|
|
||||||
return ctx.reply(`Вы сняли ${item.name}. ${resultMessages}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если предмет имеет временный эффект и уже активен
|
|
||||||
if (
|
|
||||||
item.effectData &&
|
|
||||||
Array.isArray(item.effectData) &&
|
|
||||||
item.effectData.some((effect) =>
|
|
||||||
character.activeEffects.some((activeEffect) => activeEffect.type === effect.type)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return ctx.reply(`Эффект от ${item.name} уже активен.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка эффектов предмета
|
|
||||||
if (item.effectData && Array.isArray(item.effectData)) {
|
|
||||||
const resultMessages = processEffects(character, item.effectData, true); // true, так как мы снаряжаем предмет
|
|
||||||
|
|
||||||
// Удаляем предмет из инвентаря, если он одноразовый
|
|
||||||
if (item.type === 'consumable') {
|
|
||||||
await character.removeItemFromInventory(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если предмет не одноразовый, снаряжаем его
|
|
||||||
else {
|
|
||||||
await character.addEquippedItem(item); // Добавляем предмет в снаряженные
|
|
||||||
}
|
|
||||||
|
|
||||||
await character.save(); // Явно сохраняем изменения в базе данных
|
|
||||||
return ctx.reply(resultMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.reply('Этот предмет нельзя использовать.');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
rpg.command('shop', async (ctx) => {
|
|
||||||
const character = await CharacterModel.findByPk(ctx.from.id);
|
const character = await CharacterModel.findByPk(ctx.from.id);
|
||||||
|
|
||||||
if (!character) {
|
if (!character) {
|
||||||
return ctx.reply('Персонаж не найден!');
|
return ctx.reply('Персонаж не найден.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.equipped) {
|
||||||
|
return ctx.reply(`${item.name} уже снаряжен.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Применяем эффекты предмета
|
||||||
|
if (item.effectData) {
|
||||||
|
const resultMessages = processEffects(character, item.effectData, true);
|
||||||
|
await ctx.reply(resultMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Снаряжаем предмет
|
||||||
|
item.equipped = true;
|
||||||
|
await item.save();
|
||||||
|
|
||||||
|
ctx.reply(`Вы успешно снарядили ${item.name}.`);
|
||||||
|
});
|
||||||
|
|
||||||
|
rpg.action(/unequip_item_(\d+)/, async (ctx) => {
|
||||||
|
const itemId = parseInt(ctx.match[1], 10);
|
||||||
|
const character = await CharacterModel.findByPk(ctx.from.id);
|
||||||
|
const item = await InventoryModel.findByPk(itemId);
|
||||||
|
|
||||||
|
if (!item || item.telegram_id != ctx.from.id) {
|
||||||
|
return ctx.reply('Этот предмет не найден в вашем инвентаре.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item.equipped) {
|
||||||
|
return ctx.reply(`${item.name} не снаряжен.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.effectData) {
|
||||||
|
const resultMessages = processEffects(character, item.effectData, false);
|
||||||
|
await ctx.reply(resultMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.equipped = false;
|
||||||
|
await item.save();
|
||||||
|
|
||||||
|
ctx.reply(`Вы успешно сняли ${item.name}.`);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
rpg.action('shop', async (ctx) => {
|
||||||
const items = await ItemsModel.findAll();
|
const items = await ItemsModel.findAll();
|
||||||
|
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
@ -925,130 +983,166 @@ rpg.command('shop', async (ctx) => {
|
|||||||
|
|
||||||
let message = 'Добро пожаловать в магазин! Здесь вы можете купить предметы:\n\n';
|
let message = 'Добро пожаловать в магазин! Здесь вы можете купить предметы:\n\n';
|
||||||
|
|
||||||
const buttons = items.map((item) => {
|
// Генерируем кнопки, каждая кнопка будет в отдельной строке
|
||||||
return [Markup.button.callback(`${item.name} - ${item.price}₽`, `buy_item_${item.id}`)];
|
const buttons = items.map((item) => [
|
||||||
});
|
Markup.button.callback(`${item.name} - ${item.price}₽`, `buy_item_${item.id}`)
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Отправляем сообщение с клавиатурой
|
||||||
await ctx.reply(message, Markup.inlineKeyboard(buttons));
|
await ctx.reply(message, Markup.inlineKeyboard(buttons));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
rpg.action(/buy_item_(\d+)/, async (ctx) => {
|
rpg.action(/buy_item_(\d+)/, async (ctx) => {
|
||||||
const itemId = parseInt(ctx.match[1], 10);
|
const itemId = parseInt(ctx.match[1], 10);
|
||||||
const character = await CharacterModel.findByPk(ctx.from.id);
|
|
||||||
const item = await ItemsModel.findByPk(itemId);
|
const item = await ItemsModel.findByPk(itemId);
|
||||||
|
|
||||||
if (!character || !item) {
|
if (!item) {
|
||||||
return ctx.reply('Ошибка: Персонаж или предмет не найдены.');
|
return ctx.reply('Предмет не найден.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const character = await CharacterModel.findByPk(ctx.from.id);
|
||||||
|
|
||||||
|
if (!character) {
|
||||||
|
return ctx.reply('Персонаж не найден.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (character.balance < item.price) {
|
if (character.balance < item.price) {
|
||||||
return ctx.reply('У вас недостаточно средств для покупки этого предмета.');
|
return ctx.reply('У вас недостаточно средств для покупки этого предмета.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Снимаем деньги с баланса персонажа
|
// Снимаем деньги с баланса
|
||||||
character.balance -= item.price;
|
character.balance -= item.price;
|
||||||
|
|
||||||
// Добавляем предмет в инвентарь (в массив)
|
// Добавляем предмет в инвентарь
|
||||||
character.inventory = [...character.inventory, item];
|
await InventoryModel.create({
|
||||||
|
telegram_id: ctx.from.id,
|
||||||
|
name: item.name,
|
||||||
|
description: item.description,
|
||||||
|
effectData: item.effectData,
|
||||||
|
price: item.price,
|
||||||
|
rarity: item.rarity,
|
||||||
|
type: item.type,
|
||||||
|
duration: item.duration,
|
||||||
|
equipped: false,
|
||||||
|
});
|
||||||
|
|
||||||
await character.save();
|
await character.save();
|
||||||
|
ctx.reply(`Вы успешно купили ${item.name} за ${item.price}₽!`);
|
||||||
// Отправляем сообщение об успешной покупке
|
|
||||||
await ctx.reply(`Вы успешно купили ${item.name} за ${item.price}₽!`);
|
|
||||||
|
|
||||||
// Можно добавить сюда логику для применения эффекта, если он есть
|
|
||||||
});
|
});
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CharacterModel.prototype.addEquippedItem = async function(item) {
|
CharacterModel.prototype.addEquippedItem = async function (item) {
|
||||||
// Проверяем, есть ли уже предмет в инвентаре
|
// Проверяем, находится ли предмет в инвентаре персонажа
|
||||||
const isInInventory = this.inventory.some((invItem) => invItem.id === item.id);
|
const inventoryItem = await InventoryModel.findOne({
|
||||||
if (!isInInventory) {
|
where: { telegram_id: this.telegram_id, id: item.id },
|
||||||
return; // Предмет должен быть в инвентаре
|
});
|
||||||
|
|
||||||
|
if (!inventoryItem) {
|
||||||
|
throw new Error('Предмет не найден в вашем инвентаре.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверяем, есть ли уже этот предмет в снаряженных
|
// Проверяем, не снаряжен ли уже этот предмет
|
||||||
if (!this.equippedItems.some((equippedItem) => equippedItem.id === item.id)) {
|
if (inventoryItem.equipped) {
|
||||||
this.equippedItems.push(item.id); // Добавляем только ID предмета
|
throw new Error('Этот предмет уже снаряжен.');
|
||||||
this.changed('equippedItems', true); // Помечаем, что поле изменилось
|
|
||||||
await this.save(); // Сохраняем изменения в базе данных
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
// Снаряжаем предмет
|
||||||
|
inventoryItem.equipped = true;
|
||||||
|
await inventoryItem.save();
|
||||||
|
|
||||||
|
// Применяем эффекты предмета
|
||||||
|
let resultMessages = [];
|
||||||
|
if (inventoryItem.effectData) {
|
||||||
|
resultMessages = processEffects(this, inventoryItem.effectData, true);
|
||||||
|
await this.save(); // Сохраняем изменения в характеристиках персонажа
|
||||||
|
}
|
||||||
|
|
||||||
CharacterModel.prototype.removeEquippedItem = async function(item) {
|
|
||||||
// Проверяем, снаряжен ли предмет
|
|
||||||
if (this.equippedItems.some((equippedItem) => equippedItem.id === item.id)) {
|
|
||||||
// Убираем эффект, если он связан с данным предметом
|
|
||||||
if (item.effectData && Array.isArray(item.effectData)) {
|
|
||||||
const resultMessages = processEffects(this, item.effectData, false); // false, так как мы снимаем
|
|
||||||
this.changed('equippedItems', true); // Помечаем изменение массива снаряженных
|
|
||||||
await this.save();
|
|
||||||
return resultMessages;
|
return resultMessages;
|
||||||
}
|
|
||||||
|
|
||||||
// Удаляем предмет из снаряженных
|
|
||||||
this.equippedItems = this.equippedItems.filter((equippedItem) => equippedItem.id !== item.id);
|
|
||||||
this.changed('equippedItems', true); // Помечаем изменение массива снаряженных
|
|
||||||
await this.save(); // Сохраняем изменения в базе данных
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CharacterModel.prototype.removeEquippedItem = async function (item) {
|
||||||
|
// Проверяем, находится ли предмет в инвентаре персонажа
|
||||||
|
const inventoryItem = await InventoryModel.findOne({
|
||||||
|
where: { telegram_id: this.telegram_id, id: item.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!inventoryItem || !inventoryItem.equipped) {
|
||||||
|
throw new Error('Этот предмет не снаряжен.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Снимаем предмет
|
||||||
|
inventoryItem.equipped = false;
|
||||||
|
await inventoryItem.save();
|
||||||
|
|
||||||
|
// Убираем эффекты предмета
|
||||||
|
let resultMessages = [];
|
||||||
|
if (inventoryItem.effectData) {
|
||||||
|
resultMessages = processEffects(this, inventoryItem.effectData, false);
|
||||||
|
await this.save(); // Сохраняем изменения в характеристиках персонажа
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultMessages;
|
||||||
|
};
|
||||||
|
|
||||||
const processEffects = (character, effects, isEquipping) => {
|
const processEffects = (character, effects, isEquipping) => {
|
||||||
let messages = [];
|
let messages = [];
|
||||||
|
|
||||||
effects.forEach((effect) => {
|
effects.forEach((effect) => {
|
||||||
// Если предмет снимается (isEquipping = false), эффекты снимаются
|
|
||||||
if (!isEquipping) {
|
if (!isEquipping) {
|
||||||
|
// Снимаем эффекты
|
||||||
switch (effect.type) {
|
switch (effect.type) {
|
||||||
case 'damage_boost':
|
case 'damage_boost':
|
||||||
character.force -= effect.amount;
|
character.force = Math.max(0, character.force - effect.amount);
|
||||||
|
character.save()
|
||||||
messages.push(`Ваш урон уменьшен на ${effect.amount}.`);
|
messages.push(`Ваш урон уменьшен на ${effect.amount}.`);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'max_health_boost':
|
case 'max_health_boost':
|
||||||
character.max_hp -= effect.amount;
|
character.max_hp = Math.max(1, character.max_hp - effect.amount);
|
||||||
|
character.save()
|
||||||
messages.push(`Ваше максимальное здоровье уменьшено на ${effect.amount}.`);
|
messages.push(`Ваше максимальное здоровье уменьшено на ${effect.amount}.`);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'stamina_penalty':
|
case 'stamina_penalty':
|
||||||
character.max_stamina += effect.amount;
|
character.max_stamina += effect.amount;
|
||||||
|
character.save()
|
||||||
messages.push(`Ваша выносливость увеличена на ${effect.amount}.`);
|
messages.push(`Ваша выносливость увеличена на ${effect.amount}.`);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
messages.push('Эффект не распознан при снятии.');
|
messages.push('Неизвестный эффект при снятии.');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Применяем эффект при снаряжении
|
// Применяем эффекты
|
||||||
switch (effect.type) {
|
switch (effect.type) {
|
||||||
case 'heal':
|
case 'heal':
|
||||||
const maxHp = character.maxHp || 100;
|
character.hp = Math.min(character.max_hp, character.hp + effect.amount);
|
||||||
character.hp = Math.min(maxHp, character.hp + effect.amount);
|
character.save()
|
||||||
messages.push(`Вы восстановили ${effect.amount} HP.`);
|
messages.push(`Вы восстановили ${effect.amount} HP.`);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'damage_boost':
|
case 'damage_boost':
|
||||||
character.force += effect.amount;
|
character.force += effect.amount;
|
||||||
|
character.save()
|
||||||
messages.push(`Ваш урон увеличен на ${effect.amount}.`);
|
messages.push(`Ваш урон увеличен на ${effect.amount}.`);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'max_health_boost':
|
case 'max_health_boost':
|
||||||
character.max_hp += effect.amount;
|
character.max_hp += effect.amount;
|
||||||
|
character.save()
|
||||||
messages.push(`Ваше максимальное здоровье увеличено на ${effect.amount}.`);
|
messages.push(`Ваше максимальное здоровье увеличено на ${effect.amount}.`);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'stamina_penalty':
|
case 'stamina_penalty':
|
||||||
character.max_stamina -= effect.amount;
|
character.max_stamina -= effect.amount;
|
||||||
|
character.save()
|
||||||
messages.push(`Ваша выносливость уменьшена на ${effect.amount}.`);
|
messages.push(`Ваша выносливость уменьшена на ${effect.amount}.`);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
messages.push('Эффект не распознан при надевании.');
|
messages.push('Неизвестный эффект при снаряжении.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1056,8 +1150,6 @@ const processEffects = (character, effects, isEquipping) => {
|
|||||||
return messages.join('\n');
|
return messages.join('\n');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function generateKeyboard() {
|
function generateKeyboard() {
|
||||||
const buttonsCount = 10;
|
const buttonsCount = 10;
|
||||||
const buttons = [];
|
const buttons = [];
|
||||||
|
Loading…
Reference in New Issue
Block a user