Battle refactor
This commit is contained in:
Degradin 2025-01-23 02:08:24 +03:00
parent 7b53c7ea08
commit c145b6763f
4 changed files with 11979 additions and 99 deletions

16
bot.js
View File

@ -76,6 +76,22 @@ bot.telegram.setMyCommands([{
{ {
command: "report", command: "report",
description: "Создать жалобу/обращение/идею." description: "Создать жалобу/обращение/идею."
},
{
command: "materials",
description: "Купить материалы для организации."
},
{
command: "orgmessage",
description: "Отправить сообщение в организацию."
},
{
command: "payday",
description: "Получить зарплату."
},
{
command: "enterprise",
description: "Управление предприятиями."
} }
]) ])
bot.catch((err, ctx) => { bot.catch((err, ctx) => {

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ const Battle = sequelize.define('battle', {
defaultValue: "inactive" defaultValue: "inactive"
}, },
logs: { logs: {
type: DataTypes.ARRAY(DataTypes.STRING), type: DataTypes.JSON, // Используйте JSON для хранения массива
allowNull: true, allowNull: true,
defaultValue: [] defaultValue: []
}, },

152
rpg.js
View File

@ -54,13 +54,6 @@ rpg.use(async (ctx, next) => {
await next(); // Передаем управление следующему middleware await next(); // Передаем управление следующему middleware
}); });
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) => { rpg.action('rpg_profile', async (ctx) => {
const telegramId = ctx.from.id; const telegramId = ctx.from.id;
@ -2145,11 +2138,10 @@ rpg.action(/use_grenade_\d+/, async (ctx) => {
for (const battle of activeBattles) { for (const battle of activeBattles) {
battle.enemy_hp -= damage; battle.enemy_hp -= damage;
battle.logs.push(`💣 Враг получил ${damage} урона от гранаты.`); await addBattleLog(battle, `💣 Враг получил ${damage} урона от гранаты.`);
if (battle.enemy_hp <= 0) { if (battle.enemy_hp <= 0) {
battle.status = "completed"; battle.status = "completed";
battle.logs.push("💀 Враг был убит гранатой."); await addBattleLog(battle, "💀 Враг был убит гранатой.");
} }
await battle.save({ fields: ["enemy_hp", "logs", "status"] }); await battle.save({ fields: ["enemy_hp", "logs", "status"] });
@ -2197,7 +2189,7 @@ rpg.action(/start_battle_\d+/, async (ctx) => {
const startBattle = async (ctx, character, enemy, battle) => { const startBattle = async (ctx, character, enemy, battle) => {
await ctx.reply( await ctx.reply(
`⚔️ Начинается сражение!\n\nВаш противник: ${enemy.name}\n🛡️ Уровень: ${enemy.level}\n❤️ Здоровье: ${enemy.hp}\n\nВы готовы?`, `⚔️ Начинается сражение!\n\nВаш противник: ${enemy.name}\n🛡️ Уровень: ${enemy.level}\n❤️ Здоровье: ${enemy.hp}\n\nВы готовы?`,
Markup.inlineKeyboard([[{ text: "Атаковать", callback_data: `attack_${battle.id}` }]]) Markup.inlineKeyboard([[{ text: "Атаковать", callback_data: `attack` }]])
); );
logs(ctx, "Начало сражения", { enemy, battle }); logs(ctx, "Начало сражения", { enemy, battle });
}; };
@ -2207,17 +2199,15 @@ const enemyTurn = async (ctx, character, battle) => {
const dodgeChance = Math.min(character.resilience * 0.05, 0.5); const dodgeChance = Math.min(character.resilience * 0.05, 0.5);
const isDodged = Math.random() < dodgeChance; const isDodged = Math.random() < dodgeChance;
// Генерация кнопок
const buttons = generateBattleButtons(character, battle);
const keyboard = Markup.inlineKeyboard(buttons);
// Логи битвы
const battlelogs = battle.logs || [];
const logMessage = battlelogs.slice(-5).map((log) => `${log}`).join("\n");
if (isDodged) { if (isDodged) {
// Генерация кнопок
const buttons = await generateBattleButtons();
const keyboard = Markup.inlineKeyboard(buttons);
// Сообщение с информацией // Сообщение с информацией
battle.logs.push(`💨 ${character.name} уклонились от атаки противника!`); let battleLogs = await addBattleLog(battle, `💨 ${character.name} уклонился от атаки ${enemy.name}!`);
await battle.save({ fields: ["logs"] }); // Логи битвы
let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
logs(ctx, "Уклонение от атаки", { enemy, battle }); logs(ctx, "Уклонение от атаки", { enemy, battle });
return await ctx.editMessageText( return await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` + `⚔️ Сражение с ${enemy.name}\n\n` +
@ -2231,38 +2221,43 @@ const enemyTurn = async (ctx, character, battle) => {
const damage = enemy.damage; const damage = enemy.damage;
character.hp -= damage; character.hp -= damage;
await character.save();
if (character.hp <= 0) { if (character.hp <= 0) {
battle.status = "inactive"; battle.status = "inactive";
battle.logs.push( let battleLogs = await addBattleLog(battle, `💔 ${enemy.name} нанес ${character.name} ${damage} урона!\n\n${character.name} потерпел поражение от ${enemy.name}.`);
`💔 Противник нанес ${character.name} ${damage} урона!\n\n${character.name} потерпел поражение от ${enemy.name}.` await battle.save({ fields: ["logs", "status"] });
);
// При проигрыше игрок потеряет деньги или экипированные предметы // При проигрыше игрок потеряет деньги или экипированные предметы
const inventory = await InventoryModel.findAll({ where: { telegram_id: ctx.from.id } }); const inventory = await InventoryModel.findAll({ where: { telegram_id: ctx.from.id } });
const equippedItems = inventory.filter((item) => item.equipped); const equippedItems = inventory.filter((item) => item.equipped);
if (equippedItems.length) { if (equippedItems.length) {
const randomItem = equippedItems[Math.floor(Math.random() * equippedItems.length)]; const randomItem = equippedItems[Math.floor(Math.random() * equippedItems.length)];
// Снимаем предмет и снимает эффекты с персонажа // Снимаем предмет и снимает эффекты с персонажа
if (randomItem) {
processEffects(character, randomItem.effectData, false); processEffects(character, randomItem.effectData, false);
randomItem.equipped = false;
await randomItem.destroy(); await randomItem.destroy();
battle.logs.push(`💼 ${character.name} потерял ${randomItem.name}.`); await addBattleLog(battle, `💼 ${character.name} потерял ${randomItem.name}.`);
}
} else { } else {
// Теряет 10% от денег // Теряет 10% от денег
const lostMoney = Math.floor(character.dirtymoney * 0.1); const lostMoney = Math.floor(character.dirtymoney * 0.1);
character.dirtymoney -= lostMoney; character.dirtymoney -= lostMoney;
battle.logs.push(`💰 ${character.name} потерял ${lostMoney} монет.`); await addBattleLog(battle, `💰 ${character.name} потерял ${lostMoney} монет.`);
} }
await character.save(); await character.save();
await battle.save({ fields: ["logs", "status"] }); await battle.save({ fields: ["logs", "status"] });
let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
logs(ctx, "Поражение персонажа", { enemy, battle }); logs(ctx, "Поражение персонажа", { enemy, battle });
return await ctx.editMessageText( `⚔️ Вы проиграли!\n\n` + `💔 Противник нанес ${character.name} ${damage} урона!\n\n` + `📜 Логи битвы:\n${logMessage || "Пока ничего не произошло."}`); return await ctx.editMessageText( `⚔️ Вы проиграли!\n\n` + `💔 ${enemy.name} нанес ${character.name} ${damage} урона!\n\n` + `📜 Логи битвы:\n${logMessage || "Пока ничего не произошло."}`);
} }
await character.save(); let battleLogs = await addBattleLog(battle, `💔 ${enemy.name} нанес ${character.name} ${damage} урона. У ${character.name} осталось ${character.hp} HP.`);
battle.logs.push(`💔 Противник нанес ${character.name} ${damage} урона. У ${character.name} осталось ${character.hp} HP.`); let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
await battle.save({ fields: ["logs"] });
logs(ctx, "Атака врага", { enemy, battle, damage }); logs(ctx, "Атака врага", { enemy, battle, damage });
// Генерация кнопок
const buttons = await generateBattleButtons();
const keyboard = Markup.inlineKeyboard(buttons);
console.log(buttons)
return await ctx.editMessageText( return await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` + `⚔️ Сражение с ${enemy.name}\n\n` +
`❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` + `❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` +
@ -2273,56 +2268,11 @@ const enemyTurn = async (ctx, character, battle) => {
); );
}; };
rpg.action(/attack_\d+/, async (ctx) => { async function generateBattleButtons() {
const battleId = ctx.match[0].split("_")[1];
const battle = await Battle.findByPk(battleId);
if (!battle || battle.status !== "active") {
logs(ctx, "Сражение завершено или не существует", { battleId });
return ctx.reply("Сражение завершено или не существует.");
}
const character = await CharacterModel.findOne({ where: { telegram_id: ctx.from.id } });
if (!character || battle.character != ctx.from.id) {
logs(ctx, "Персонаж не найден или не участвует в битве", { telegramId: ctx.from.id, battleId });
return ctx.reply("Это не ваша битва.");
}
const enemy = await Enemy.findByPk(battle.enemy);
if (!enemy) {
logs(ctx, "Противник не найден", { enemyId: battle.enemy });
return ctx.reply("Противник не найден.");
}
if (character.stamina < enemy.level * 3) {
logs(ctx, "Недостаточно стамины", { character, enemy });
return ctx.reply("У вас недостаточно стамины для атаки.");
}
character.stamina -= enemy.level * 3;
await character.save();
// Генерация кнопок
const buttons = generateBattleButtons(character, battle);
const keyboard = Markup.inlineKeyboard(buttons);
// Логи битвы
const battlelogs = battle.logs || [];
const logMessage = battlelogs.slice(-5).map((log) => `${log}`).join("\n");
// Сообщение с информацией
logs(ctx, "Атака", { enemyId: battle.enemy });
await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` +
`❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` +
`⚔️ Урон врага: ${enemy.damage}\n\n` +
`📜 Логи битвы:\n${logMessage || "Пока ничего не произошло."}\n\n` +
`🎯 Выберите цель для атаки:`,
keyboard
);
});
async function generateBattleButtons(character) {
const buttons = [ const buttons = [
{ {
text: "🗡️ Атака", text: "🗡️ Атака",
callback_data: "hit", callback_data: "attack",
}, },
{ {
text: "🛡️ Защита", text: "🛡️ Защита",
@ -2330,7 +2280,7 @@ async function generateBattleButtons(character) {
}, },
]; ];
return [buttons]; // Кнопки выводятся в одной строке return buttons.map((btn) => [btn]);
} }
@ -2507,45 +2457,51 @@ rpg.action("attack", async (ctx) => {
battle.enemy_hp -= damage; battle.enemy_hp -= damage;
} else { } else {
// Промах — враг делает ход // Промах — враг делает ход
await enemyTurn(ctx, character, battle); return await enemyTurn(ctx, character, battle);
} }
// Логи боя // Логи боя
battle.logs = battle.logs || []; let battleLogs = await addBattleLog(battle, `${character.name} нанес ${damage} урона (${result}).`);
battle.logs.push(`${character.name} нанес ${damage} урона (${result}).`); await battle.save();
await battle.save({ fields: ["enemy_hp", "logs"] });
// Проверка на победу // Проверка на победу
if (battle.enemy_hp <= 0) { if (battle.enemy_hp <= 0) {
battle.status = "completed"; battle.status = "completed";
await battle.save(); await battle.save();
let items = ""; let items = '';
Exp(ctx, character, enemy.level * 6); Exp(ctx, character, enemy.level * 6)
character.enemiesKilled += 1; character.enemiesKilled += 1;
await character.save(); await character.save();
const droppedItems = await dropItem(character, enemy.id); let droppedItems = await dropItem(character, enemy.id);
logs(ctx, "Предметы с врага", { droppedItems });
if (droppedItems.length > 0) { if (droppedItems) {
for (const item of droppedItems) { for (const item of droppedItems) {
await InventoryModel.create({ await InventoryModel.create({
telegram_id: character.telegram_id, telegram_id: character.telegram_id,
...item, // Запись всех параметров предмета name: item.name,
text_id: item.text_id,
description: item.description,
effectData: item.effectData,
price: item.price,
rarity: item.rarity,
type: item.type,
duration: item.duration,
canBeEquipped: item.canBeEquipped,
equipped: false,
img: item.img
}); });
} }
items = droppedItems.map((item) => item.name).join(", "); items = droppedItems.map((item) => item.name).join(", ");
} }
let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
return ctx.editMessageText( return ctx.editMessageText(
`🎉 ${character.name} победил ${enemy.name}!\n\n📜 Логи битвы:\n${battle.logs `🎉 ${character.name} победил ${enemy.name}!\n\n📜 Логи битвы:\n${logMessage}\n🧩 Выпавшие предметы: ${items}`
.slice(-5)
.map((log) => `${log}`)
.join("\n")}\n🧩 Выпавшие предметы: ${items}`
); );
} }
// Продолжение боя // Продолжение боя
const logMessage = battle.logs.slice(-5).map((log) => `${log}`).join("\n"); let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
const buttons = generateBattleButtons(character); const buttons = await generateBattleButtons();
const keyboard = Markup.inlineKeyboard(buttons); const keyboard = Markup.inlineKeyboard(buttons);
await ctx.editMessageText( await ctx.editMessageText(
@ -2557,6 +2513,14 @@ rpg.action("attack", async (ctx) => {
); );
}); });
async function addBattleLog(battle, logMessage) {
if (!battle.logs) battle.logs = []; // Инициализация массива, если он пустой
// Добавляем перед сообщением дату и время до миллисекунды
logMessage = `[${new Date().toISOString()}] ${logMessage}`;
battle.logs.push(logMessage);
await battle.save({ fields: ["logs"] }); // Сохранение изменений
return battle.logs; // Возвращаем обновленный массив логов
}
rpg.command('checkstats', async (ctx) => { rpg.command('checkstats', async (ctx) => {