Files
HTML-Game/kripto-magnat.html
T

820 lines
39 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Крипто-Магнат</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', sans-serif;
background: linear-gradient(135deg, #0a0e27 0%, #1a1a3e 100%);
color: #fff; min-height: 100vh; padding: 20px;
}
.container { max-width: 1400px; margin: 0 auto; }
h1 { text-align: center; margin-bottom: 30px; font-size: 42px;
background: linear-gradient(135deg, #00f2fe, #4facfe);
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
text-shadow: 0 0 30px rgba(79, 172, 254, 0.5); }
.status-bar {
background: rgba(0,0,0,0.4); border-radius: 15px;
padding: 20px; margin-bottom: 20px;
display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px;
backdrop-filter: blur(10px); border: 1px solid rgba(79, 172, 254, 0.2);
}
.status-item { text-align: center; }
.status-label { font-size: 11px; opacity: 0.7; text-transform: uppercase; letter-spacing: 1px; }
.status-value { font-size: 24px; font-weight: bold; color: #00f2fe; margin-top: 5px; }
.tabs {
display: flex; gap: 10px; margin-bottom: 20px;
background: rgba(0,0,0,0.3); padding: 10px; border-radius: 12px;
}
.tab {
flex: 1; padding: 12px; border: none; border-radius: 8px;
background: rgba(255,255,255,0.05); color: #fff; cursor: pointer;
font-size: 14px; font-weight: bold; transition: all 0.3s;
}
.tab.active { background: linear-gradient(135deg, #00f2fe, #4facfe); }
.tab:hover:not(.active) { background: rgba(255,255,255,0.1); }
.tab-content { display: none; }
.tab-content.active { display: block; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 768px) { .grid { grid-template-columns: 1fr; } }
.card {
background: rgba(0,0,0,0.4); border-radius: 12px;
padding: 20px; backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.1);
}
.card h2 { margin-bottom: 15px; color: #00f2fe; font-size: 20px; }
.crypto-item {
background: rgba(255,255,255,0.05); padding: 15px;
border-radius: 8px; margin-bottom: 10px;
display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 10px;
align-items: center; border: 1px solid rgba(255,255,255,0.05);
}
.crypto-name { font-weight: bold; font-size: 16px; }
.crypto-price { color: #00f2fe; font-size: 18px; font-weight: bold; }
.crypto-change { font-size: 14px; }
.crypto-change.up { color: #4caf50; }
.crypto-change.down { color: #f44336; }
.btn {
padding: 8px 16px; border: none; border-radius: 6px;
font-size: 13px; font-weight: bold; cursor: pointer;
color: white; transition: all 0.2s;
}
.btn-buy { background: linear-gradient(135deg, #4caf50, #45a049); }
.btn-sell { background: linear-gradient(135deg, #f44336, #d32f2f); }
.btn-transfer { background: linear-gradient(135deg, #ff9800, #f57c00); }
.btn-action { background: linear-gradient(135deg, #9c27b0, #7b1fa2); }
.btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0,0,0,0.3); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.progress-bar {
background: rgba(255,255,255,0.1); border-radius: 10px;
height: 30px; overflow: hidden; margin: 10px 0;
position: relative;
}
.progress-fill {
height: 100%; background: linear-gradient(90deg, #00f2fe, #4facfe);
transition: width 0.5s; display: flex; align-items: center;
justify-content: center; font-weight: bold; font-size: 14px;
}
.shop-item {
background: rgba(255,255,255,0.05); padding: 15px;
border-radius: 8px; margin-bottom: 10px;
display: flex; justify-content: space-between; align-items: center;
border: 1px solid rgba(255,255,255,0.05);
}
.shop-item.owned { border-color: #4caf50; background: rgba(76, 175, 80, 0.1); }
.item-info { flex: 1; }
.item-name { font-weight: bold; font-size: 16px; margin-bottom: 5px; }
.item-desc { font-size: 12px; opacity: 0.7; }
.item-price { color: #ffd700; font-weight: bold; margin-right: 15px; }
.log {
background: rgba(0,0,0,0.5); border-radius: 8px;
padding: 10px; margin-top: 20px; font-family: monospace;
font-size: 12px; max-height: 200px; overflow-y: auto;
border: 1px solid rgba(255,255,255,0.1);
}
.log-entry { margin-bottom: 3px; padding: 2px 0; }
.log-entry.error { color: #f44336; }
.log-entry.success { color: #4caf50; }
.log-entry.info { color: #aaa; }
.log-entry.warning { color: #ff9800; }
.api-status {
position: fixed; top: 10px; left: 10px;
padding: 8px 16px; border-radius: 20px;
font-size: 12px; background: rgba(0, 0, 0, 0.7);
color: #aaa; z-index: 1000;
}
.api-status.connected { color: #4caf50; }
.api-status.error { color: #f44336; }
.transfer-section {
background: rgba(255, 152, 0, 0.1); border: 1px solid rgba(255, 152, 0, 0.3);
border-radius: 8px; padding: 15px; margin-bottom: 15px;
}
.transfer-section h3 { color: #ff9800; margin-bottom: 10px; font-size: 16px; }
.transfer-input {
width: 100%; padding: 10px; border: 1px solid rgba(255,255,255,0.2);
border-radius: 6px; background: rgba(0,0,0,0.3); color: #fff;
margin-bottom: 10px; font-size: 14px;
}
.construction-stage {
background: rgba(255,255,255,0.05); padding: 15px;
border-radius: 8px; margin-bottom: 10px;
border: 1px solid rgba(255,255,255,0.05);
}
.construction-stage.completed { border-color: #4caf50; background: rgba(76, 175, 80, 0.1); }
.construction-stage.active { border-color: #00f2fe; background: rgba(0, 242, 254, 0.1); }
</style>
</head>
<body>
<div class="api-status" id="apiStatus">⏳ API: ожидание...</div>
<div class="container">
<h1>💎 Крипто-Магнат</h1>
<div class="status-bar">
<div class="status-item">
<div class="status-label">💵 Наличные</div>
<div class="status-value" id="cash">0</div>
</div>
<div class="status-item">
<div class="status-label">₿ Крипто</div>
<div class="status-value" id="cryptoValue">0</div>
</div>
<div class="status-item">
<div class="status-label">🏢 Бизнесы</div>
<div class="status-value" id="businessIncome">0/сек</div>
</div>
<div class="status-item">
<div class="status-label">🏠 Дом</div>
<div class="status-value" id="houseLevel">0%</div>
</div>
</div>
<div class="tabs">
<button class="tab active" data-tab="crypto">₿ Биржа</button>
<button class="tab" data-tab="transfer">💸 Переводы</button>
<button class="tab" data-tab="house">🏠 Дом</button>
<button class="tab" data-tab="business">🏢 Бизнесы</button>
<button class="tab" data-tab="luxury">💎 Роскошь</button>
</div>
<!-- КРИПТО БИРЖА -->
<div class="tab-content active" id="crypto">
<div class="grid">
<div class="card">
<h2>📊 Криптовалюты</h2>
<div id="cryptoList"></div>
</div>
<div class="card">
<h2>💼 Мой портфель</h2>
<div id="portfolio"></div>
</div>
</div>
</div>
<!-- ПЕРЕВОДЫ -->
<div class="tab-content" id="transfer">
<div class="grid">
<div class="card">
<h2>📥 Ввод средств</h2>
<div class="transfer-section">
<h3>Из Кликера</h3>
<p style="font-size: 13px; opacity: 0.7; margin-bottom: 10px;">
Доступно: <span id="clickerAvailable">0</span>
</p>
<input type="number" class="transfer-input" id="fromClicker" placeholder="Сумма">
<button class="btn btn-transfer" onclick="transferFrom('clicker')">Перевести</button>
</div>
<div class="transfer-section">
<h3>Из Инвестора</h3>
<p style="font-size: 13px; opacity: 0.7; margin-bottom: 10px;">
Доступно: <span id="investorAvailable">0</span>
</p>
<input type="number" class="transfer-input" id="fromInvestor" placeholder="Сумма">
<button class="btn btn-transfer" onclick="transferFrom('investor')">Перевести</button>
</div>
</div>
<div class="card">
<h2>📤 Вывод средств</h2>
<div class="transfer-section">
<h3>В Кликер</h3>
<input type="number" class="transfer-input" id="toClicker" placeholder="Сумма">
<button class="btn btn-transfer" onclick="transferTo('clicker')">Перевести</button>
</div>
<div class="transfer-section">
<h3>В Инвестор</h3>
<input type="number" class="transfer-input" id="toInvestor" placeholder="Сумма">
<button class="btn btn-transfer" onclick="transferTo('investor')">Перевести</button>
</div>
</div>
</div>
</div>
<!-- СТРОИТЕЛЬСТВО ДОМА -->
<div class="tab-content" id="house">
<div class="card">
<h2>🏗️ Строительство дома</h2>
<div id="constructionStages"></div>
</div>
</div>
<!-- БИЗНЕСЫ -->
<div class="tab-content" id="business">
<div class="card">
<h2>🏢 Мои бизнесы</h2>
<div id="businessList"></div>
</div>
</div>
<!-- РОСКОШЬ -->
<div class="tab-content" id="luxury">
<div class="card">
<h2>💎 Предметы роскоши</h2>
<div id="luxuryList"></div>
</div>
</div>
<div class="log" id="log"></div>
</div>
<script>
// ═══════════════════════════════════════════════════════════
// КОНФИГУРАЦИЯ
// ══════════════════════════════════════════════════════════
const CLICKER_SAVE = 'main_save';
const CLICKER_TABLE = 'game_save';
const INVESTOR_SAVE = 'investor_save';
const INVESTOR_TABLE = 'investor_data';
const MY_SAVE = 'crypto_save';
const MY_TABLE = 'crypto_data';
let myState = {
cash: 10000,
portfolio: {},
businesses: {},
luxury: {},
house: { stage: 0, progress: 0 }
};
const cryptos = {
BTC: { name: 'Bitcoin', price: 50000, change: 0 },
ETH: { name: 'Ethereum', price: 3000, change: 0 },
DOGE: { name: 'Dogecoin', price: 0.15, change: 0 },
SOL: { name: 'Solana', price: 120, change: 0 },
SHIB: { name: 'Shiba Inu', price: 0.000025, change: 0 }
};
const houseStages = [
{ name: 'Фундамент', cost: 50000, time: 60 },
{ name: 'Стены', cost: 100000, time: 120 },
{ name: 'Крыша', cost: 75000, time: 90 },
{ name: 'Отделка', cost: 150000, time: 180 },
{ name: 'Мебель', cost: 200000, time: 240 }
];
const businesses = [
{ id: 'shop1', name: 'Продуктовый магазин', cost: 25000, income: 50 },
{ id: 'shop2', name: 'Одежда', cost: 75000, income: 150 },
{ id: 'shop3', name: 'Ресторан', cost: 200000, income: 400 },
{ id: 'shop4', name: 'Автосалон', cost: 500000, income: 1000 },
{ id: 'shop5', name: 'Торговый центр', cost: 2000000, income: 5000 }
];
const luxuryItems = [
{ id: 'watch1', name: '⌚ Часы Rolex', cost: 50000, desc: 'Статус +10%' },
{ id: 'car1', name: '🚗 Tesla Model S', cost: 150000, desc: 'Статус +20%' },
{ id: 'suit1', name: '👔 Костюм Brioni', cost: 75000, desc: 'Статус +15%' },
{ id: 'yacht1', name: '🛥️ Яхта', cost: 1000000, desc: 'Статус +50%' },
{ id: 'jet1', name: '✈️ Частный самолёт', cost: 5000000, desc: 'Статус +100%' }
];
let api = null;
const statusEl = document.getElementById('apiStatus');
function updateStatus(text, type = '') {
statusEl.textContent = text;
statusEl.className = 'api-status ' + type;
}
function log(msg, type = 'info') {
const el = document.getElementById('log');
const entry = document.createElement('div');
entry.className = 'log-entry ' + type;
entry.textContent = `[${new Date().toLocaleTimeString()}] ${msg}`;
el.insertBefore(entry, el.firstChild);
while (el.children.length > 50) el.removeChild(el.lastChild);
}
// ═══════════════════════════════════════════════════════════
// API ИНИЦИАЛИЗАЦИЯ
// ═══════════════════════════════════════════════════════════
window.addEventListener('gameApiReady', async () => {
api = window.gameApi;
updateStatus('✓ API подключён', 'connected');
log('API подключён', 'success');
try {
await api.createTable(MY_TABLE, {
'key': 'TEXT', 'value': 'TEXT'
}, MY_SAVE, 'Данные крипто-магната');
log('Таблица создана', 'success');
} catch (e) {
log('Таблица уже существует');
}
await loadState();
updateUI();
renderCrypto();
renderHouse();
renderBusinesses();
renderLuxury();
setInterval(tick, 1000);
setInterval(updateCryptoPrices, 3000);
setInterval(saveState, 10000);
});
setTimeout(() => {
if (!api) {
updateStatus('✗ API недоступен', 'error');
log('API недоступен', 'error');
}
}, 5000);
// ═══════════════════════════════════════════════════════════
// СОХРАНЕНИЕ / ЗАГРУЗКА
// ═══════════════════════════════════════════════════════════
async function loadState() {
if (!api) return;
try {
const result = await api.selectData(MY_TABLE, { key: 'state' }, MY_SAVE);
if (result.data && result.data.length > 0) {
myState = JSON.parse(result.data[0].value);
log('Состояние загружено', 'success');
}
} catch (e) {
log('Ошибка загрузки: ' + e.message, 'error');
}
}
async function saveState() {
if (!api) return;
try {
await api.deleteData(MY_TABLE, { key: 'state' }, MY_SAVE);
await api.insertData(MY_TABLE, {
key: 'state',
value: JSON.stringify(myState),
updated_at: new Date().toISOString()
}, MY_SAVE);
} catch (e) {
log('Ошибка сохранения: ' + e.message, 'error');
}
}
// ═══════════════════════════════════════════════════════════
// КРИПТО БИРЖА
// ═══════════════════════════════════════════════════════════
function updateCryptoPrices() {
for (let symbol in cryptos) {
const change = (Math.random() - 0.5) * 0.1;
cryptos[symbol].change = change;
cryptos[symbol].price *= (1 + change);
}
renderCrypto();
updateUI();
}
function renderCrypto() {
const list = document.getElementById('cryptoList');
list.innerHTML = '';
for (let symbol in cryptos) {
const crypto = cryptos[symbol];
const changeClass = crypto.change >= 0 ? 'up' : 'down';
const changeSign = crypto.change >= 0 ? '+' : '';
list.innerHTML += `
<div class="crypto-item">
<div>
<div class="crypto-name">${symbol}</div>
<div style="font-size: 12px; opacity: 0.7;">${crypto.name}</div>
</div>
<div class="crypto-price">$${crypto.price.toFixed(2)}</div>
<div class="crypto-change ${changeClass}">${changeSign}${(crypto.change * 100).toFixed(2)}%</div>
<div>
<button class="btn btn-buy" onclick="buyCrypto('${symbol}')">Купить</button>
<button class="btn btn-sell" onclick="sellCrypto('${symbol}')" ${myState.portfolio[symbol] ? '' : 'disabled'}>Продать</button>
</div>
</div>
`;
}
renderPortfolio();
}
function renderPortfolio() {
const portfolio = document.getElementById('portfolio');
let totalValue = 0;
let html = '';
for (let symbol in myState.portfolio) {
const amount = myState.portfolio[symbol];
const value = amount * cryptos[symbol].price;
totalValue += value;
html += `
<div class="crypto-item">
<div class="crypto-name">${symbol}</div>
<div>${amount.toFixed(6)}</div>
<div class="crypto-price">$${value.toFixed(2)}</div>
</div>
`;
}
if (html === '') {
html = '<div style="text-align:center;opacity:0.5;padding:20px">Портфель пуст</div>';
}
portfolio.innerHTML = html;
document.getElementById('cryptoValue').textContent = '$' + Math.floor(totalValue).toLocaleString();
}
function buyCrypto(symbol) {
const amount = parseFloat(prompt(`Сколько ${symbol} купить? (цена: $${cryptos[symbol].price.toFixed(2)})`));
if (!amount || amount <= 0) return;
const cost = amount * cryptos[symbol].price;
if (myState.cash < cost) {
log('Недостаточно средств', 'error');
return;
}
myState.cash -= cost;
myState.portfolio[symbol] = (myState.portfolio[symbol] || 0) + amount;
log(`Куплено ${amount} ${symbol} за $${cost.toFixed(2)}`, 'success');
renderCrypto();
updateUI();
}
function sellCrypto(symbol) {
const amount = parseFloat(prompt(`Сколько ${symbol} продать? (есть: ${myState.portfolio[symbol]})`));
if (!amount || amount <= 0) return;
if (myState.portfolio[symbol] < amount) {
log('Недостаточно криптовалюты', 'error');
return;
}
const revenue = amount * cryptos[symbol].price;
myState.cash += revenue;
myState.portfolio[symbol] -= amount;
if (myState.portfolio[symbol] < 0.000001) delete myState.portfolio[symbol];
log(`Продано ${amount} ${symbol} за $${revenue.toFixed(2)}`, 'success');
renderCrypto();
updateUI();
}
// ═══════════════════════════════════════════════════════════
// ПЕРЕВОДЫ
// ═══════════════════════════════════════════════════════════
async function transferFrom(source) {
if (!api) { log('API недоступен', 'error'); return; }
const input = document.getElementById(source === 'clicker' ? 'fromClicker' : 'fromInvestor');
const amount = parseFloat(input.value);
if (!amount || amount <= 0) { log('Введите сумму', 'error'); return; }
try {
let sourceTable, sourceSave, sourceKey;
if (source === 'clicker') {
sourceTable = CLICKER_TABLE;
sourceSave = CLICKER_SAVE;
sourceKey = 'game_state';
} else {
sourceTable = INVESTOR_TABLE;
sourceSave = INVESTOR_SAVE;
sourceKey = 'state';
}
const result = await api.selectData(sourceTable, { key: sourceKey }, sourceSave, {}, source);
if (!result.data || result.data.length === 0) {
log('Источник не найден', 'error');
return;
}
const state = JSON.parse(result.data[0].value);
const available = source === 'clicker' ? state.score : state.capital;
if (available < amount) {
log('Недостаточно средств в источнике', 'error');
return;
}
if (source === 'clicker') {
state.score -= amount;
} else {
state.capital -= amount;
}
await api.deleteData(sourceTable, { key: sourceKey }, sourceSave, false, source);
await api.insertData(sourceTable, {
key: sourceKey,
value: JSON.stringify(state),
updated_at: new Date().toISOString()
}, sourceSave, source);
myState.cash += amount;
log(`Получено $${amount} из ${source}`, 'success');
input.value = '';
updateUI();
await refreshAvailable();
} catch (e) {
log('Ошибка перевода: ' + e.message, 'error');
}
}
async function transferTo(target) {
if (!api) { log('API недоступен', 'error'); return; }
const input = document.getElementById(target === 'clicker' ? 'toClicker' : 'toInvestor');
const amount = parseFloat(input.value);
if (!amount || amount <= 0) { log('Введите сумму', 'error'); return; }
if (myState.cash < amount) { log('Недостаточно средств', 'error'); return; }
try {
let targetTable, targetSave, targetKey;
if (target === 'clicker') {
targetTable = CLICKER_TABLE;
targetSave = CLICKER_SAVE;
targetKey = 'game_state';
} else {
targetTable = INVESTOR_TABLE;
targetSave = INVESTOR_SAVE;
targetKey = 'state';
}
const result = await api.selectData(targetTable, { key: targetKey }, targetSave, {}, target);
if (!result.data || result.data.length === 0) {
log('Цель не найдена', 'error');
return;
}
const state = JSON.parse(result.data[0].value);
if (target === 'clicker') {
state.score += amount;
} else {
state.capital += amount;
}
await api.deleteData(targetTable, { key: targetKey }, targetSave, false, target);
await api.insertData(targetTable, {
key: targetKey,
value: JSON.stringify(state),
updated_at: new Date().toISOString()
}, targetSave, target);
myState.cash -= amount;
log(`Отправлено $${amount} в ${target}`, 'success');
input.value = '';
updateUI();
} catch (e) {
log('Ошибка перевода: ' + e.message, 'error');
}
}
async function refreshAvailable() {
if (!api) return;
try {
const clickerResult = await api.selectData(CLICKER_TABLE, { key: 'game_state' }, CLICKER_SAVE, {}, 'clicker');
if (clickerResult.data && clickerResult.data.length > 0) {
const state = JSON.parse(clickerResult.data[0].value);
document.getElementById('clickerAvailable').textContent = Math.floor(state.score || 0).toLocaleString();
}
const investorResult = await api.selectData(INVESTOR_TABLE, { key: 'state' }, INVESTOR_SAVE, {}, 'investor');
if (investorResult.data && investorResult.data.length > 0) {
const state = JSON.parse(investorResult.data[0].value);
document.getElementById('investorAvailable').textContent = Math.floor(state.capital || 0).toLocaleString();
}
} catch (e) {
log('Ошибка обновления: ' + e.message, 'error');
}
}
// ═══════════════════════════════════════════════════════════
// СТРОИТЕЛЬСТВО ДОМА
// ═══════════════════════════════════════════════════════════
function renderHouse() {
const container = document.getElementById('constructionStages');
container.innerHTML = '';
houseStages.forEach((stage, index) => {
const isCompleted = myState.house.stage > index;
const isActive = myState.house.stage === index;
const progress = isActive ? myState.house.progress : (isCompleted ? 100 : 0);
container.innerHTML += `
<div class="construction-stage ${isCompleted ? 'completed' : ''} ${isActive ? 'active' : ''}">
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<div>
<div style="font-weight: bold; font-size: 16px;">${stage.name}</div>
<div style="font-size: 12px; opacity: 0.7;">Стоимость: $${stage.cost.toLocaleString()} | Время: ${stage.time}с</div>
</div>
${isActive ? `<button class="btn btn-action" onclick="buildStage()">Строить</button>` : ''}
${isCompleted ? '<div style="color: #4caf50; font-weight: bold;">✓ Готово</div>' : ''}
</div>
${isActive ? `
<div class="progress-bar">
<div class="progress-fill" style="width: ${progress}%">${Math.floor(progress)}%</div>
</div>
` : ''}
</div>
`;
});
}
function buildStage() {
if (myState.house.stage >= houseStages.length) {
log('Дом полностью построен!', 'success');
return;
}
const stage = houseStages[myState.house.stage];
if (myState.cash < stage.cost) {
log('Недостаточно средств', 'error');
return;
}
myState.cash -= stage.cost;
myState.house.progress = 0;
log(`Начато строительство: ${stage.name}`, 'success');
renderHouse();
updateUI();
}
// ═══════════════════════════════════════════════════════════
// БИЗНЕСЫ
// ═══════════════════════════════════════════════════════════
function renderBusinesses() {
const container = document.getElementById('businessList');
container.innerHTML = '';
businesses.forEach(biz => {
const owned = myState.businesses[biz.id];
container.innerHTML += `
<div class="shop-item ${owned ? 'owned' : ''}">
<div class="item-info">
<div class="item-name">${biz.name}</div>
<div class="item-desc">Доход: $${biz.income}/сек</div>
</div>
<div class="item-price">$${biz.cost.toLocaleString()}</div>
<button class="btn ${owned ? 'btn-action' : 'btn-buy'}"
onclick="${owned ? 'manageBusiness' : 'buyBusiness'}('${biz.id}')"
${!owned && myState.cash < biz.cost ? 'disabled' : ''}>
${owned ? '⚙️ Управление' : '🛒 Купить'}
</button>
</div>
`;
});
}
function buyBusiness(id) {
const biz = businesses.find(b => b.id === id);
if (myState.cash < biz.cost) {
log('Недостаточно средств', 'error');
return;
}
myState.cash -= biz.cost;
myState.businesses[id] = { workers: 1, efficiency: 1 };
log(`Куплен бизнес: ${biz.name}`, 'success');
renderBusinesses();
updateUI();
}
function manageBusiness(id) {
const biz = businesses.find(b => b.id === id);
const action = prompt(`Управление: ${biz.name}\n1. Нанять работника ($${biz.cost / 10})\n2. Уволить работника\n3. Улучшить эффективность ($${biz.cost / 5})\nВведите номер:`);
if (action === '1') {
const cost = biz.cost / 10;
if (myState.cash < cost) { log('Недостаточно средств', 'error'); return; }
myState.cash -= cost;
myState.businesses[id].workers++;
log(`Нанят работник в ${biz.name}`, 'success');
} else if (action === '2') {
if (myState.businesses[id].workers > 1) {
myState.businesses[id].workers--;
log(`Работник уволен из ${biz.name}`, 'info');
} else {
log('Нельзя уволить последнего работника', 'error');
}
} else if (action === '3') {
const cost = biz.cost / 5;
if (myState.cash < cost) { log('Недостаточно средств', 'error'); return; }
myState.cash -= cost;
myState.businesses[id].efficiency *= 1.5;
log(`Улучшена эффективность ${biz.name}`, 'success');
}
renderBusinesses();
updateUI();
}
// ═══════════════════════════════════════════════════════════
// РОСКОШЬ
// ═══════════════════════════════════════════════════════════
function renderLuxury() {
const container = document.getElementById('luxuryList');
container.innerHTML = '';
luxuryItems.forEach(item => {
const owned = myState.luxury[item.id];
container.innerHTML += `
<div class="shop-item ${owned ? 'owned' : ''}">
<div class="item-info">
<div class="item-name">${item.name}</div>
<div class="item-desc">${item.desc}</div>
</div>
<div class="item-price">$${item.cost.toLocaleString()}</div>
<button class="btn ${owned ? 'btn-action' : 'btn-buy'}"
onclick="buyLuxury('${item.id}')"
${owned || myState.cash < item.cost ? 'disabled' : ''}>
${owned ? '✓ Куплено' : '🛒 Купить'}
</button>
</div>
`;
});
}
function buyLuxury(id) {
const item = luxuryItems.find(i => i.id === id);
if (myState.cash < item.cost) {
log('Недостаточно средств', 'error');
return;
}
myState.cash -= item.cost;
myState.luxury[id] = true;
log(`Куплено: ${item.name}`, 'success');
renderLuxury();
updateUI();
}
// ═══════════════════════════════════════════════════════════
// ИГРОВОЙ ЦИКЛ
// ═══════════════════════════════════════════════════════════
function tick() {
// Доход от бизнесов
let totalIncome = 0;
for (let id in myState.businesses) {
const biz = businesses.find(b => b.id === id);
const data = myState.businesses[id];
const income = biz.income * data.workers * data.efficiency;
totalIncome += income;
}
if (totalIncome > 0) {
myState.cash += totalIncome;
}
// Строительство дома
if (myState.house.stage < houseStages.length && myState.house.progress > 0) {
const stage = houseStages[myState.house.stage];
myState.house.progress += (100 / stage.time);
if (myState.house.progress >= 100) {
myState.house.stage++;
myState.house.progress = 0;
log(`Этап "${stage.name}" завершён!`, 'success');
renderHouse();
}
}
updateUI();
}
function updateUI() {
document.getElementById('cash').textContent = '$' + Math.floor(myState.cash).toLocaleString();
let totalIncome = 0;
for (let id in myState.businesses) {
const biz = businesses.find(b => b.id === id);
const data = myState.businesses[id];
totalIncome += biz.income * data.workers * data.efficiency;
}
document.getElementById('businessIncome').textContent = '$' + Math.floor(totalIncome).toLocaleString() + '/сек';
const housePercent = Math.floor((myState.house.stage / houseStages.length) * 100);
document.getElementById('houseLevel').textContent = housePercent + '%';
}
// ═══════════════════════════════════════════════════════════
// ВКЛАДКИ
// ═══════════════════════════════════════════════════════════
document.querySelectorAll('.tab').forEach(tab => {
tab.onclick = () => {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
tab.classList.add('active');
document.getElementById(tab.dataset.tab).classList.add('active');
if (tab.dataset.tab === 'transfer') refreshAvailable();
};
});
updateUI();
</script>
</body>
</html>