v0.0.4
This commit is contained in:
parent
c7a5bdea26
commit
1f509dbffb
178
bot.js
178
bot.js
@ -375,7 +375,7 @@ bot.hears('🏗️ Предприятия', async (ctx) => {
|
|||||||
} else {
|
} else {
|
||||||
buttons.push([{ text: '🗄️ Построить склад', callback_data: 'buy_warehouse' }]);
|
buttons.push([{ text: '🗄️ Построить склад', callback_data: 'buy_warehouse' }]);
|
||||||
}
|
}
|
||||||
|
buttons.push([{ text: '💰 Продать ресурсы', callback_data: 'sell_resources' }])
|
||||||
// Возвращаем меню с кнопками
|
// Возвращаем меню с кнопками
|
||||||
return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize());
|
return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize());
|
||||||
});
|
});
|
||||||
@ -405,7 +405,7 @@ bot.action('enterprise_menu', async (ctx) => {
|
|||||||
} else {
|
} else {
|
||||||
buttons.push([{ text: '🗄️ Построить склад', callback_data: 'buy_warehouse' }]);
|
buttons.push([{ text: '🗄️ Построить склад', callback_data: 'buy_warehouse' }]);
|
||||||
}
|
}
|
||||||
|
buttons.push([{ text: '💰 Продать ресурсы', callback_data: 'sell_resources' }])
|
||||||
// Возвращаем меню с кнопками
|
// Возвращаем меню с кнопками
|
||||||
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
|
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
|
||||||
});
|
});
|
||||||
@ -463,7 +463,7 @@ bot.action('my_enterprises', async (ctx) => {
|
|||||||
buttons.push(enterpriseButtons);
|
buttons.push(enterpriseButtons);
|
||||||
}
|
}
|
||||||
message += '\n\n[📈 - Улучшить]\n[🛻 - Нанять грузовик]\n 🚛 - Улучшить грузовик\n[💰 - Продать ресурсы с предприятия]\n[🔄 - Перевезти все на склад]'
|
message += '\n\n[📈 - Улучшить]\n[🛻 - Нанять грузовик]\n 🚛 - Улучшить грузовик\n[💰 - Продать ресурсы с предприятия]\n[🔄 - Перевезти все на склад]'
|
||||||
buttons.push([{ text: '⬅️ Назад', callback_data: 'back_to_menu' }]);
|
buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]);
|
||||||
|
|
||||||
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
|
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
|
||||||
});
|
});
|
||||||
@ -495,7 +495,7 @@ bot.action('build_enterprise', async (ctx) => {
|
|||||||
|
|
||||||
for (const resource of resourcePrices) {
|
for (const resource of resourcePrices) {
|
||||||
const resourceName = getEnterpriseEmoji(resource.resource);
|
const resourceName = getEnterpriseEmoji(resource.resource);
|
||||||
message += `${resourceName}: ${Math.round(resource.price)} монет\n`;
|
message += `${resourceName}: ${Math.round(resource.price)} руб.\n`;
|
||||||
|
|
||||||
// Генерируем кнопки для каждого ресурса
|
// Генерируем кнопки для каждого ресурса
|
||||||
buttons.push([
|
buttons.push([
|
||||||
@ -584,7 +584,7 @@ bot.action('buy_warehouse', async (ctx) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await user.update({ money: user.money - 500000 })
|
await user.update({ money: user.money - 500000 })
|
||||||
return await ctx.editMessageText(`Вы успешно купили единый склад!`)
|
return await ctx.reply(`Вы успешно купили единый склад!`)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Управление складом
|
// Управление складом
|
||||||
@ -607,27 +607,12 @@ bot.action('manage_warehouse', async (ctx) => {
|
|||||||
message += `💎 Алмазы: ${warehouse.diamond || 0}\n`;
|
message += `💎 Алмазы: ${warehouse.diamond || 0}\n`;
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
[{ text: '➕ Перевести ресурсы', callback_data: 'transfer_resources' }],
|
[{ text: '➕ Перевести ресурсы', callback_data: 'transfer_resources' }]
|
||||||
[{ text: '📤 Продать со склада', callback_data: 'sell_from_warehouse' }],
|
|
||||||
[{ text: '🚚 Купить транспорт', callback_data: 'buy_truck' }]
|
|
||||||
];
|
];
|
||||||
|
buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]);
|
||||||
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
|
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Управление предприятием
|
|
||||||
bot.action(/manage_(\d+)/, async (ctx) => {
|
|
||||||
let enterpriseId = ctx.match[1]
|
|
||||||
let enterprise = await EnterpriseModel.findByPk(enterpriseId)
|
|
||||||
|
|
||||||
if (!enterprise) return await ctx.reply(`Предприятие не найдено.`)
|
|
||||||
const buttons = [
|
|
||||||
[{ text: 'Продать ресурсы', callback_data: 'sell_resources' }],
|
|
||||||
[{ text: 'Нанять грузовик', callback_data: 'hire_truck' }]
|
|
||||||
];
|
|
||||||
// Логика управления предприятием (например, прокачка или продажа ресурсов)
|
|
||||||
return await ctx.reply(`Вы управляете предприятием ${enterprise.name} (ID: ${enterprise.id}).`, Markup.inlineKeyboard(buttons).resize())
|
|
||||||
})
|
|
||||||
bot.action('transfer_resources', async (ctx) => {
|
bot.action('transfer_resources', async (ctx) => {
|
||||||
const user = await UserModel.findByPk(ctx.from.id);
|
const user = await UserModel.findByPk(ctx.from.id);
|
||||||
const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } });
|
const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } });
|
||||||
@ -647,7 +632,7 @@ bot.action('transfer_resources', async (ctx) => {
|
|||||||
const buttons = enterprises.map(ent => {
|
const buttons = enterprises.map(ent => {
|
||||||
return [{ text: `🏭 ${ent.name}`, callback_data: `transfer_from_${ent.id}` }];
|
return [{ text: `🏭 ${ent.name}`, callback_data: `transfer_from_${ent.id}` }];
|
||||||
});
|
});
|
||||||
|
buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]);
|
||||||
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
|
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -738,7 +723,7 @@ bot.action(/upgrade_(\d+)/, async (ctx) => {
|
|||||||
|
|
||||||
let upgradeCost = enterprise.level * 100 // Стоимость улучшения зависит от уровня
|
let upgradeCost = enterprise.level * 100 // Стоимость улучшения зависит от уровня
|
||||||
if (user.balance < upgradeCost) {
|
if (user.balance < upgradeCost) {
|
||||||
return await ctx.reply(`У вас недостаточно средств для прокачки предприятия. Необходимо ${upgradeCost} монет.`)
|
return await ctx.reply(`У вас недостаточно средств для прокачки предприятия. Необходимо ${upgradeCost} руб.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Прокачка: повышение уровня и эффективности
|
// Прокачка: повышение уровня и эффективности
|
||||||
@ -761,17 +746,28 @@ bot.action('sell_resources', async (ctx) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (enterprises.length === 0) {
|
if (enterprises.length === 0) {
|
||||||
return await ctx.reply('У вас нет предприятий для продажи ресурсов.');
|
return await ctx.reply('❌ У вас нет предприятий для продажи ресурсов.');
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = 'Список ваших предприятий и их ресурсы:\n\n';
|
let message = `<b>📜 Список ваших предприятий и их ресурсы:</b>\n\n`;
|
||||||
enterprises.forEach((enterprise, index) => {
|
enterprises.forEach((enterprise, index) => {
|
||||||
message += `${index + 1}. ${enterprise.name} (${enterprise.resourceType}): ${enterprise.currentResources} единиц\n`;
|
message += `<b>${index + 1}.</b> ${enterprise.name} (${enterprise.resourceType}): <b>${enterprise.currentResources}</b> единиц\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
message += `\nЧтобы продать ресурсы, используйте команду:\n/sellres <номер_предприятия> <количество>\nПример: /sellres 1 50`;
|
message += `\n<b>📦 Продажа ресурсов:</b>\n`;
|
||||||
return await ctx.reply(message);
|
message += `• Для продажи ресурсов с предприятия используйте команду:\n<code>/sellres [номер_предприятия] [количество]</code>\n<i>Пример:</i> <code>/sellres 1 50</code>\n\n`;
|
||||||
|
message += `• Для продажи ресурсов со склада используйте команду:\n<code>/sellstorage [тип_ресурса (wood/coal/oil/metall/gold/diamond)] [количество]</code>\n<i>Пример:</i> <code>/sellstorage wood 10</code>`;
|
||||||
|
|
||||||
|
return await ctx.reply(message, {
|
||||||
|
parse_mode: 'HTML',
|
||||||
|
reply_markup: {
|
||||||
|
inline_keyboard: [
|
||||||
|
[{ text: '↩ Назад', callback_data: 'enterprise_menu' }]
|
||||||
|
]
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Обработка продажи ресурсов
|
// Обработка продажи ресурсов
|
||||||
bot.command('sellres', async (ctx) => {
|
bot.command('sellres', async (ctx) => {
|
||||||
@ -819,9 +815,9 @@ bot.command('sellres', async (ctx) => {
|
|||||||
user.money += totalSale;
|
user.money += totalSale;
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
// Инфляция: уменьшение цены ресурса
|
// Ослабленная инфляция
|
||||||
resourcePrice.price = Math.round(
|
resourcePrice.price = Math.round(
|
||||||
resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * amount)
|
resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * (amount / 10)) // Дробное уменьшение инфляции
|
||||||
);
|
);
|
||||||
|
|
||||||
// Гарантируем, что цена не упадет ниже 50% от базовой цены
|
// Гарантируем, что цена не упадет ниже 50% от базовой цены
|
||||||
@ -830,28 +826,50 @@ bot.command('sellres', async (ctx) => {
|
|||||||
await resourcePrice.save();
|
await resourcePrice.save();
|
||||||
|
|
||||||
return await ctx.reply(
|
return await ctx.reply(
|
||||||
`Вы продали ${amount} единиц ${enterprise.resourceType} с предприятия ${enterprise.name} за ${totalSale} монет.\nТекущая цена за единицу: ${resourcePrice.price.toFixed(0)} монет.`
|
`Вы продали ${amount} единиц ${enterprise.resourceType} с предприятия ${enterprise.name} за ${totalSale} руб.\nТекущая цена за единицу: ${resourcePrice.price.toFixed(0)} руб.`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Восстановление цен ресурсов
|
|
||||||
const recoverResourcePrices = async () => {
|
const recoverResourcePrices = async () => {
|
||||||
const resources = await ResourcePriceModel.findAll();
|
const resources = await ResourcePriceModel.findAll();
|
||||||
|
|
||||||
for (const resource of resources) {
|
for (const resource of resources) {
|
||||||
|
// Определяем случайное колебание в диапазоне [-maxFluctuation, maxFluctuation]
|
||||||
|
const maxFluctuation = resource.basePrice * 0.03; // 3% от базовой цены
|
||||||
|
const priceFluctuation = (Math.random() * 2 - 1) * maxFluctuation;
|
||||||
|
|
||||||
|
// Применяем колебание
|
||||||
|
resource.price = Math.round(resource.price + priceFluctuation);
|
||||||
|
|
||||||
|
// Если цена выше базовой, шанс на её снижение
|
||||||
|
if (resource.price > resource.basePrice) {
|
||||||
|
const chanceToDrop = 0.6; // 60% шанс на снижение
|
||||||
|
if (Math.random() < chanceToDrop) {
|
||||||
|
resource.price -= Math.round(resource.basePrice * 0.01); // Снижение на 1% базовой цены
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если цена ниже базовой, восстанавливаем с учётом recoveryRate
|
||||||
if (resource.price < resource.basePrice) {
|
if (resource.price < resource.basePrice) {
|
||||||
resource.price = Math.min(
|
resource.price = Math.min(
|
||||||
resource.price + resource.basePrice * resource.recoveryRate,
|
Math.round(resource.price + resource.basePrice * resource.recoveryRate),
|
||||||
resource.basePrice // Не превышать базовую цену
|
resource.basePrice // Не превышать базовую цену
|
||||||
);
|
);
|
||||||
await resource.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Гарантируем, что цена остаётся в диапазоне [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 * 1.5)); // Максимум
|
||||||
|
|
||||||
|
await resource.save(); // Сохраняем после всех корректировок
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Запускаем процесс восстановления цен каждые 15 минут
|
// Запускаем процесс восстановления цен каждые 15 минут
|
||||||
setInterval(recoverResourcePrices, 15 * 60 * 1000);
|
setInterval(recoverResourcePrices, 5 * 1000);
|
||||||
|
|
||||||
bot.action(/sell_all_(\d+)/, async (ctx) => {
|
bot.action(/sell_all_(\d+)/, async (ctx) => {
|
||||||
const enterpriseId = ctx.match[1];
|
const enterpriseId = ctx.match[1];
|
||||||
@ -903,9 +921,9 @@ bot.action(/confirm_ressell_(\d+)/, async (ctx) => {
|
|||||||
|
|
||||||
await user.save();
|
await user.save();
|
||||||
await enterprise.save();
|
await enterprise.save();
|
||||||
// Инфляция: уменьшение цены ресурса
|
// Ослабленная инфляция
|
||||||
resourcePrice.price = Math.round(
|
resourcePrice.price = Math.round(
|
||||||
resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * amount)
|
resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * (amount / 10)) // Дробное уменьшение инфляции
|
||||||
);
|
);
|
||||||
|
|
||||||
// Гарантируем, что цена не упадет ниже 50% от базовой цены
|
// Гарантируем, что цена не упадет ниже 50% от базовой цены
|
||||||
@ -913,7 +931,64 @@ bot.action(/confirm_ressell_(\d+)/, async (ctx) => {
|
|||||||
|
|
||||||
await resourcePrice.save();
|
await resourcePrice.save();
|
||||||
|
|
||||||
await ctx.reply(`Вы успешно продали ${currentResources} ед. ${resourceType} за ${totalPrice} руб.`);
|
await ctx.editMessageText(`Вы успешно продали ${currentResources} ед. ${resourceType} за ${totalPrice} руб.`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Продажа ресурсов со склада
|
||||||
|
bot.command('sellstorage', async (ctx) => {
|
||||||
|
const user = await UserModel.findByPk(ctx.from.id);
|
||||||
|
const [resourceType, amountToSell] = ctx.message.text.split(' ').slice(1);
|
||||||
|
|
||||||
|
if (!resourceType || !amountToSell) {
|
||||||
|
return await ctx.reply('Неверный формат команды. Пример: /sellstorage <тип_ресурса> <количество>');
|
||||||
|
}
|
||||||
|
|
||||||
|
const storage = await WarehouseModel.findOne({
|
||||||
|
where: { playerId: user.telegram_id }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!storage || !storage[resourceType]) {
|
||||||
|
return await ctx.reply(`У вас нет ресурсов типа ${resourceType} на складе.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const amount = parseInt(amountToSell, 10);
|
||||||
|
|
||||||
|
if (isNaN(amount) || amount <= 0) {
|
||||||
|
return await ctx.reply('Укажите корректное количество для продажи.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storage[resourceType] < amount) {
|
||||||
|
return await ctx.reply(`На складе недостаточно ресурсов типа ${resourceType}. Доступно: ${storage[resourceType]} единиц.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourcePrice = await ResourcePriceModel.findOne({ where: { resource: resourceType } });
|
||||||
|
|
||||||
|
if (!resourcePrice) {
|
||||||
|
return await ctx.reply('Не удалось получить цену ресурса.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalSale = Math.floor(amount * resourcePrice.price);
|
||||||
|
|
||||||
|
// Обновляем данные
|
||||||
|
storage[resourceType] -= amount;
|
||||||
|
await storage.save();
|
||||||
|
|
||||||
|
user.money += totalSale;
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
// Ослабленная инфляция
|
||||||
|
resourcePrice.price = Math.round(
|
||||||
|
resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * (amount / 10)) // Дробное уменьшение инфляции
|
||||||
|
);
|
||||||
|
|
||||||
|
// Гарантируем, что цена не упадет ниже 50% от базовой цены
|
||||||
|
resourcePrice.price = Math.max(resourcePrice.price, Math.round(resourcePrice.basePrice * 0.5));
|
||||||
|
|
||||||
|
await resourcePrice.save();
|
||||||
|
|
||||||
|
return await ctx.reply(
|
||||||
|
`Вы продали ${amount} ед. ${resourceType} со склада за ${totalSale} руб.\nТекущая цена за единицу: ${resourcePrice.price.toFixed(0)} руб.`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Найм грузовика
|
// Найм грузовика
|
||||||
@ -976,12 +1051,12 @@ bot.action(/hire_truck_(\d+)/, async (ctx) => {
|
|||||||
|
|
||||||
async function initializePrices() {
|
async function initializePrices() {
|
||||||
const resources = [
|
const resources = [
|
||||||
{ resource: 'wood', price: 10000, basePrice: 10000, fluctuationRate: 0.1, recoveryRate: 0.01 },
|
{ resource: 'wood', price: 1000, basePrice: 1000, fluctuationRate: 0.002, recoveryRate: 0.15 },
|
||||||
{ resource: 'coal', price: 20000, basePrice: 20000, fluctuationRate: 0.1, recoveryRate: 0.01 },
|
{ resource: 'coal', price: 2000, basePrice: 2000, fluctuationRate: 0.002, recoveryRate: 0.12 },
|
||||||
{ resource: 'oil', price: 50000, basePrice: 50000, fluctuationRate: 0.1, recoveryRate: 0.01 },
|
{ resource: 'oil', price: 5000, basePrice: 5000, fluctuationRate: 0.001, recoveryRate: 0.1 },
|
||||||
{ resource: 'metall', price: 100000, basePrice: 100000, fluctuationRate: 0.1, recoveryRate: 0.01 },
|
{ resource: 'metall', price: 5000, basePrice: 5000, fluctuationRate: 0.001, recoveryRate: 0.1 },
|
||||||
{ resource: 'gold', price: 300000, basePrice: 300000, fluctuationRate: 0.1, recoveryRate: 0.01 },
|
{ resource: 'gold', price: 10000, basePrice: 10000, fluctuationRate: 0.0005, recoveryRate: 0.08 },
|
||||||
{ resource: 'diamond', price: 500000, basePrice: 500000, fluctuationRate: 0.1, recoveryRate: 0.01 },
|
{ resource: 'diamond', price: 25000, basePrice: 25000, fluctuationRate: 0.0004, recoveryRate: 0.05 },
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const resource of resources) {
|
for (const resource of resources) {
|
||||||
@ -994,19 +1069,6 @@ async function initializePrices() {
|
|||||||
|
|
||||||
initializePrices();
|
initializePrices();
|
||||||
|
|
||||||
setInterval(async () => {
|
|
||||||
const resources = await ResourcePriceModel.findAll()
|
|
||||||
for (let resource of resources) {
|
|
||||||
if (resource.price < resource.basePrice) {
|
|
||||||
resource.price += resource.recoveryRate
|
|
||||||
if (resource.price > resource.basePrice) {
|
|
||||||
resource.price = resource.basePrice
|
|
||||||
}
|
|
||||||
await resource.save()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 60000) // Обновляем цены каждые 60 секунд
|
|
||||||
|
|
||||||
// Функция добычи ресурсов
|
// Функция добычи ресурсов
|
||||||
const resourceProduction = async () => {
|
const resourceProduction = async () => {
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user