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",
description: "Создать жалобу/обращение/идею."
},
{
command: "materials",
description: "Купить материалы для организации."
},
{
command: "orgmessage",
description: "Отправить сообщение в организацию."
},
{
command: "payday",
description: "Получить зарплату."
},
{
command: "enterprise",
description: "Управление предприятиями."
}
])
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"
},
logs: {
type: DataTypes.ARRAY(DataTypes.STRING),
type: DataTypes.JSON, // Используйте JSON для хранения массива
allowNull: true,
defaultValue: []
},

158
rpg.js
View File

@ -54,13 +54,6 @@ rpg.use(async (ctx, next) => {
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) => {
const telegramId = ctx.from.id;
@ -2145,11 +2138,10 @@ rpg.action(/use_grenade_\d+/, async (ctx) => {
for (const battle of activeBattles) {
battle.enemy_hp -= damage;
battle.logs.push(`💣 Враг получил ${damage} урона от гранаты.`);
await addBattleLog(battle, `💣 Враг получил ${damage} урона от гранаты.`);
if (battle.enemy_hp <= 0) {
battle.status = "completed";
battle.logs.push("💀 Враг был убит гранатой.");
await addBattleLog(battle, "💀 Враг был убит гранатой.");
}
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) => {
await ctx.reply(
`⚔️ Начинается сражение!\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 });
};
@ -2207,17 +2199,15 @@ const enemyTurn = async (ctx, character, battle) => {
const dodgeChance = Math.min(character.resilience * 0.05, 0.5);
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) {
// Сообщение с информацией
battle.logs.push(`💨 ${character.name} уклонились от атаки противника!`);
await battle.save({ fields: ["logs"] });
// Генерация кнопок
const buttons = await generateBattleButtons();
const keyboard = Markup.inlineKeyboard(buttons);
// Сообщение с информацией
let battleLogs = await addBattleLog(battle, `💨 ${character.name} уклонился от атаки ${enemy.name}!`);
// Логи битвы
let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
logs(ctx, "Уклонение от атаки", { enemy, battle });
return await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` +
@ -2231,38 +2221,43 @@ const enemyTurn = async (ctx, character, battle) => {
const damage = enemy.damage;
character.hp -= damage;
await character.save();
if (character.hp <= 0) {
battle.status = "inactive";
battle.logs.push(
`💔 Противник нанес ${character.name} ${damage} урона!\n\n${character.name} потерпел поражение от ${enemy.name}.`
);
let battleLogs = await addBattleLog(battle, `💔 ${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 equippedItems = inventory.filter((item) => item.equipped);
if (equippedItems.length) {
const randomItem = equippedItems[Math.floor(Math.random() * equippedItems.length)];
// Снимаем предмет и снимает эффекты с персонажа
processEffects(character, randomItem.effectData, false);
randomItem.equipped = false;
await randomItem.destroy();
battle.logs.push(`💼 ${character.name} потерял ${randomItem.name}.`);
if (randomItem) {
processEffects(character, randomItem.effectData, false);
await randomItem.destroy();
await addBattleLog(battle, `💼 ${character.name} потерял ${randomItem.name}.`);
}
} else {
// Теряет 10% от денег
const lostMoney = Math.floor(character.dirtymoney * 0.1);
character.dirtymoney -= lostMoney;
battle.logs.push(`💰 ${character.name} потерял ${lostMoney} монет.`);
await addBattleLog(battle, `💰 ${character.name} потерял ${lostMoney} монет.`);
}
await character.save();
await battle.save({ fields: ["logs", "status"] });
let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
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();
battle.logs.push(`💔 Противник нанес ${character.name} ${damage} урона. У ${character.name} осталось ${character.hp} HP.`);
await battle.save({ fields: ["logs"] });
let battleLogs = await addBattleLog(battle, `💔 ${enemy.name} нанес ${character.name} ${damage} урона. У ${character.name} осталось ${character.hp} HP.`);
let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
logs(ctx, "Атака врага", { enemy, battle, damage });
// Генерация кнопок
const buttons = await generateBattleButtons();
const keyboard = Markup.inlineKeyboard(buttons);
console.log(buttons)
return await ctx.editMessageText(
`⚔️ Сражение с ${enemy.name}\n\n` +
`❤️ Здоровье врага: ${battle.enemy_hp}/${enemy.hp}\n` +
@ -2273,56 +2268,11 @@ const enemyTurn = async (ctx, character, battle) => {
);
};
rpg.action(/attack_\d+/, async (ctx) => {
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) {
async function generateBattleButtons() {
const buttons = [
{
text: "🗡️ Атака",
callback_data: "hit",
callback_data: "attack",
},
{
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;
} else {
// Промах — враг делает ход
await enemyTurn(ctx, character, battle);
return await enemyTurn(ctx, character, battle);
}
// Логи боя
battle.logs = battle.logs || [];
battle.logs.push(`${character.name} нанес ${damage} урона (${result}).`);
await battle.save({ fields: ["enemy_hp", "logs"] });
let battleLogs = await addBattleLog(battle, `${character.name} нанес ${damage} урона (${result}).`);
await battle.save();
// Проверка на победу
if (battle.enemy_hp <= 0) {
battle.status = "completed";
await battle.save();
let items = "";
Exp(ctx, character, enemy.level * 6);
let items = '';
Exp(ctx, character, enemy.level * 6)
character.enemiesKilled += 1;
await character.save();
const droppedItems = await dropItem(character, enemy.id);
if (droppedItems.length > 0) {
let droppedItems = await dropItem(character, enemy.id);
logs(ctx, "Предметы с врага", { droppedItems });
if (droppedItems) {
for (const item of droppedItems) {
await InventoryModel.create({
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(", ");
}
let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
return ctx.editMessageText(
`🎉 ${character.name} победил ${enemy.name}!\n\n📜 Логи битвы:\n${battle.logs
.slice(-5)
.map((log) => `${log}`)
.join("\n")}\n🧩 Выпавшие предметы: ${items}`
`🎉 ${character.name} победил ${enemy.name}!\n\n📜 Логи битвы:\n${logMessage}\n🧩 Выпавшие предметы: ${items}`
);
}
// Продолжение боя
const logMessage = battle.logs.slice(-5).map((log) => `${log}`).join("\n");
const buttons = generateBattleButtons(character);
let logMessage = battleLogs.slice(-5).map((log) => `${log}`).join("\n");
const buttons = await generateBattleButtons();
const keyboard = Markup.inlineKeyboard(buttons);
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) => {