Обновить kripto-magnat.html
This commit is contained in:
+225
-63
@@ -30,9 +30,10 @@
|
||||
.tabs {
|
||||
display: flex; gap: 10px; margin-bottom: 20px;
|
||||
background: rgba(0,0,0,0.3); padding: 10px; border-radius: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.tab {
|
||||
flex: 1; padding: 12px; border: none; border-radius: 8px;
|
||||
flex: 1; min-width: 100px; 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;
|
||||
}
|
||||
@@ -55,14 +56,23 @@
|
||||
.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);
|
||||
border: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
.crypto-header {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.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 { font-size: 14px; margin-left: 10px; }
|
||||
.crypto-change.up { color: #4caf50; }
|
||||
.crypto-change.down { color: #f44336; }
|
||||
.crypto-buttons {
|
||||
display: flex; gap: 5px; flex-wrap: wrap;
|
||||
}
|
||||
.crypto-buttons button {
|
||||
flex: 1; min-width: 60px; padding: 8px 5px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 8px 16px; border: none; border-radius: 6px;
|
||||
@@ -76,6 +86,14 @@
|
||||
.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; }
|
||||
|
||||
.quick-buy {
|
||||
display: flex; gap: 5px; margin-top: 10px;
|
||||
}
|
||||
.quick-buy button {
|
||||
flex: 1; padding: 6px; font-size: 11px;
|
||||
background: rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
background: rgba(255,255,255,0.1); border-radius: 10px;
|
||||
height: 30px; overflow: hidden; margin: 10px 0;
|
||||
@@ -92,9 +110,10 @@
|
||||
border-radius: 8px; margin-bottom: 10px;
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
border: 1px solid rgba(255,255,255,0.05);
|
||||
flex-wrap: wrap; gap: 10px;
|
||||
}
|
||||
.shop-item.owned { border-color: #4caf50; background: rgba(76, 175, 80, 0.1); }
|
||||
.item-info { flex: 1; }
|
||||
.item-info { flex: 1; min-width: 150px; }
|
||||
.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; }
|
||||
@@ -119,6 +138,7 @@
|
||||
}
|
||||
.api-status.connected { color: #4caf50; }
|
||||
.api-status.error { color: #f44336; }
|
||||
.api-status.fallback { color: #ff9800; }
|
||||
|
||||
.transfer-section {
|
||||
background: rgba(255, 152, 0, 0.1); border: 1px solid rgba(255, 152, 0, 0.3);
|
||||
@@ -138,10 +158,20 @@
|
||||
}
|
||||
.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); }
|
||||
|
||||
.save-indicator {
|
||||
position: fixed; bottom: 10px; right: 10px;
|
||||
padding: 8px 16px; border-radius: 20px;
|
||||
font-size: 12px; background: rgba(76, 175, 80, 0.9);
|
||||
color: white; z-index: 1000;
|
||||
opacity: 0; transition: opacity 0.3s;
|
||||
}
|
||||
.save-indicator.show { opacity: 1; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="api-status" id="apiStatus">⏳ API: ожидание...</div>
|
||||
<div class="save-indicator" id="saveIndicator">💾 Сохранено!</div>
|
||||
|
||||
<div class="container">
|
||||
<h1>💎 Крипто-Магнат</h1>
|
||||
@@ -149,15 +179,15 @@
|
||||
<div class="status-bar">
|
||||
<div class="status-item">
|
||||
<div class="status-label">💵 Наличные</div>
|
||||
<div class="status-value" id="cash">0</div>
|
||||
<div class="status-value" id="cash">$10 000</div>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<div class="status-label">₿ Крипто</div>
|
||||
<div class="status-value" id="cryptoValue">0</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 class="status-value" id="businessIncome">$0/сек</div>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<div class="status-label">🏠 Дом</div>
|
||||
@@ -262,6 +292,7 @@
|
||||
const INVESTOR_TABLE = 'investor_data';
|
||||
const MY_SAVE = 'crypto_save';
|
||||
const MY_TABLE = 'crypto_data';
|
||||
const LOCAL_STORAGE_KEY = 'cryptoTycoonSave';
|
||||
|
||||
let myState = {
|
||||
cash: 10000,
|
||||
@@ -305,6 +336,7 @@
|
||||
|
||||
let api = null;
|
||||
const statusEl = document.getElementById('apiStatus');
|
||||
const saveIndicator = document.getElementById('saveIndicator');
|
||||
|
||||
function updateStatus(text, type = '') {
|
||||
statusEl.textContent = text;
|
||||
@@ -320,6 +352,11 @@
|
||||
while (el.children.length > 50) el.removeChild(el.lastChild);
|
||||
}
|
||||
|
||||
function showSaveIndicator() {
|
||||
saveIndicator.classList.add('show');
|
||||
setTimeout(() => saveIndicator.classList.remove('show'), 2000);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// API ИНИЦИАЛИЗАЦИЯ
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
@@ -351,29 +388,52 @@
|
||||
|
||||
setTimeout(() => {
|
||||
if (!api) {
|
||||
updateStatus('✗ API недоступен', 'error');
|
||||
log('API недоступен', 'error');
|
||||
updateStatus('⚠️ API недоступен, используем localStorage', 'fallback');
|
||||
log('API недоступен, работаем с localStorage', 'warning');
|
||||
loadState();
|
||||
updateUI();
|
||||
renderCrypto();
|
||||
renderHouse();
|
||||
renderBusinesses();
|
||||
renderLuxury();
|
||||
|
||||
setInterval(tick, 1000);
|
||||
setInterval(updateCryptoPrices, 3000);
|
||||
setInterval(saveState, 10000);
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// СОХРАНЕНИЕ / ЗАГРУЗКА
|
||||
// СОХРАНЕНИЕ / ЗАГРУЗКА (С FALLBACK НА LOCALSTORAGE!)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
async function loadState() {
|
||||
if (!api) return;
|
||||
if (api) {
|
||||
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');
|
||||
log('Состояние загружено из API', 'success');
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
log('Ошибка загрузки: ' + e.message, 'error');
|
||||
log('Ошибка загрузки API: ' + e.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback на localStorage
|
||||
const saved = localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||
if (saved) {
|
||||
try {
|
||||
myState = JSON.parse(saved);
|
||||
log('Состояние загружено из localStorage', 'success');
|
||||
} catch (e) {
|
||||
log('Ошибка загрузки localStorage', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function saveState() {
|
||||
if (!api) return;
|
||||
if (api) {
|
||||
try {
|
||||
await api.deleteData(MY_TABLE, { key: 'state' }, MY_SAVE);
|
||||
await api.insertData(MY_TABLE, {
|
||||
@@ -381,19 +441,44 @@
|
||||
value: JSON.stringify(myState),
|
||||
updated_at: new Date().toISOString()
|
||||
}, MY_SAVE);
|
||||
showSaveIndicator();
|
||||
return;
|
||||
} catch (e) {
|
||||
log('Ошибка сохранения: ' + e.message, 'error');
|
||||
log('Ошибка сохранения API: ' + e.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback на localStorage
|
||||
try {
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(myState));
|
||||
showSaveIndicator();
|
||||
} catch (e) {
|
||||
log('Ошибка сохранения localStorage: ' + e.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Автосохранение при закрытии страницы
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (api) {
|
||||
navigator.sendBeacon('/api/save', JSON.stringify({
|
||||
table: MY_TABLE,
|
||||
key: 'state',
|
||||
value: JSON.stringify(myState),
|
||||
save: MY_SAVE
|
||||
}));
|
||||
}
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(myState));
|
||||
});
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// КРИПТО БИРЖА
|
||||
// КРИПТО БИРЖА (ИСПРАВЛЕНО!)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
function updateCryptoPrices() {
|
||||
for (let symbol in cryptos) {
|
||||
const change = (Math.random() - 0.5) * 0.1;
|
||||
cryptos[symbol].change = change;
|
||||
cryptos[symbol].price *= (1 + change);
|
||||
if (cryptos[symbol].price < 0.000001) cryptos[symbol].price = 0.000001;
|
||||
}
|
||||
renderCrypto();
|
||||
updateUI();
|
||||
@@ -406,19 +491,34 @@
|
||||
const crypto = cryptos[symbol];
|
||||
const changeClass = crypto.change >= 0 ? 'up' : 'down';
|
||||
const changeSign = crypto.change >= 0 ? '+' : '';
|
||||
const canBuy = myState.cash >= crypto.price;
|
||||
const hasPortfolio = myState.portfolio[symbol] > 0;
|
||||
|
||||
list.innerHTML += `
|
||||
<div class="crypto-item">
|
||||
<div class="crypto-header">
|
||||
<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>
|
||||
<span class="crypto-price">$${crypto.price < 1 ? crypto.price.toFixed(6) : crypto.price.toFixed(2)}</span>
|
||||
<span class="crypto-change ${changeClass}">${changeSign}${(crypto.change * 100).toFixed(2)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="crypto-buttons">
|
||||
<button class="btn btn-buy" onclick="buyCryptoAmount('${symbol}', 100)" ${myState.cash < 100 ? 'disabled' : ''}>Купить на $100</button>
|
||||
<button class="btn btn-buy" onclick="buyCryptoAmount('${symbol}', 1000)" ${myState.cash < 1000 ? 'disabled' : ''}>Купить на $1000</button>
|
||||
<button class="btn btn-buy" onclick="buyCryptoPercent('${symbol}', 0.1)" ${myState.cash < 10 ? 'disabled' : ''}>10%</button>
|
||||
<button class="btn btn-sell" onclick="sellCryptoPercent('${symbol}', 1)" ${!hasPortfolio ? 'disabled' : ''}>Продать всё</button>
|
||||
</div>
|
||||
${hasPortfolio ? `
|
||||
<div style="margin-top: 10px; font-size: 13px; opacity: 0.8;">
|
||||
У вас: ${myState.portfolio[symbol].toFixed(6)} ${symbol}
|
||||
(≈$${(myState.portfolio[symbol] * crypto.price).toFixed(2)})
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
renderPortfolio();
|
||||
@@ -430,14 +530,23 @@
|
||||
let html = '';
|
||||
for (let symbol in myState.portfolio) {
|
||||
const amount = myState.portfolio[symbol];
|
||||
if (amount < 0.000001) continue;
|
||||
const value = amount * cryptos[symbol].price;
|
||||
totalValue += value;
|
||||
html += `
|
||||
<div class="crypto-item">
|
||||
<div class="crypto-header">
|
||||
<div class="crypto-name">${symbol}</div>
|
||||
<div>${amount.toFixed(6)}</div>
|
||||
<div class="crypto-price">$${value.toFixed(2)}</div>
|
||||
</div>
|
||||
<div style="font-size: 13px; opacity: 0.8;">
|
||||
${amount.toFixed(6)} ${symbol}
|
||||
</div>
|
||||
<button class="btn btn-sell" style="margin-top: 10px; width: 100%;"
|
||||
onclick="sellCryptoPercent('${symbol}', 1)">
|
||||
Продать всё за $${value.toFixed(2)}
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
if (html === '') {
|
||||
@@ -447,33 +556,43 @@
|
||||
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');
|
||||
// Покупка на указанную сумму в долларах (ИСПРАВЛЕНО!)
|
||||
function buyCryptoAmount(symbol, amountUsd) {
|
||||
const price = cryptos[symbol].price;
|
||||
if (myState.cash < amountUsd) {
|
||||
log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${amountUsd})`, 'error');
|
||||
return;
|
||||
}
|
||||
myState.cash -= cost;
|
||||
const amount = amountUsd / price;
|
||||
myState.cash -= amountUsd;
|
||||
myState.portfolio[symbol] = (myState.portfolio[symbol] || 0) + amount;
|
||||
log(`Куплено ${amount} ${symbol} за $${cost.toFixed(2)}`, 'success');
|
||||
log(`Куплено ${amount.toFixed(6)} ${symbol} за $${amountUsd}`, 'success');
|
||||
saveState();
|
||||
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');
|
||||
// Покупка на процент от денег
|
||||
function buyCryptoPercent(symbol, percent) {
|
||||
const amountUsd = myState.cash * percent;
|
||||
buyCryptoAmount(symbol, amountUsd);
|
||||
}
|
||||
|
||||
// Продажа процента от криптовалюты
|
||||
function sellCryptoPercent(symbol, percent) {
|
||||
if (!myState.portfolio[symbol] || myState.portfolio[symbol] < 0.000001) {
|
||||
log(`У вас нет ${symbol}`, 'error');
|
||||
return;
|
||||
}
|
||||
const amount = myState.portfolio[symbol] * percent;
|
||||
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');
|
||||
if (myState.portfolio[symbol] < 0.000001) {
|
||||
delete myState.portfolio[symbol];
|
||||
}
|
||||
log(`Продано ${amount.toFixed(6)} ${symbol} за $${revenue.toFixed(2)}`, 'success');
|
||||
saveState();
|
||||
renderCrypto();
|
||||
updateUI();
|
||||
}
|
||||
@@ -482,10 +601,10 @@
|
||||
// ПЕРЕВОДЫ
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
async function transferFrom(source) {
|
||||
if (!api) { log('API недоступен', 'error'); return; }
|
||||
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; }
|
||||
if (!amount || amount <= 0) { log('Введите корректную сумму', 'error'); return; }
|
||||
|
||||
try {
|
||||
let sourceTable, sourceSave, sourceKey;
|
||||
@@ -509,7 +628,7 @@
|
||||
const available = source === 'clicker' ? state.score : state.capital;
|
||||
|
||||
if (available < amount) {
|
||||
log('Недостаточно средств в источнике', 'error');
|
||||
log(`Недостаточно средств в источнике (есть ${Math.floor(available)}, нужно ${amount})`, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -527,8 +646,9 @@
|
||||
}, sourceSave, source);
|
||||
|
||||
myState.cash += amount;
|
||||
log(`Получено $${amount} из ${source}`, 'success');
|
||||
log(`Получено $${amount.toLocaleString()} из ${source}`, 'success');
|
||||
input.value = '';
|
||||
saveState();
|
||||
updateUI();
|
||||
await refreshAvailable();
|
||||
} catch (e) {
|
||||
@@ -537,11 +657,14 @@
|
||||
}
|
||||
|
||||
async function transferTo(target) {
|
||||
if (!api) { log('API недоступен', 'error'); return; }
|
||||
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; }
|
||||
if (!amount || amount <= 0) { log('Введите корректную сумму', 'error'); return; }
|
||||
if (myState.cash < amount) {
|
||||
log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${amount})`, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let targetTable, targetSave, targetKey;
|
||||
@@ -576,8 +699,9 @@
|
||||
}, targetSave, target);
|
||||
|
||||
myState.cash -= amount;
|
||||
log(`Отправлено $${amount} в ${target}`, 'success');
|
||||
log(`Отправлено $${amount.toLocaleString()} в ${target}`, 'success');
|
||||
input.value = '';
|
||||
saveState();
|
||||
updateUI();
|
||||
} catch (e) {
|
||||
log('Ошибка перевода: ' + e.message, 'error');
|
||||
@@ -616,12 +740,17 @@
|
||||
|
||||
container.innerHTML += `
|
||||
<div class="construction-stage ${isCompleted ? 'completed' : ''} ${isActive ? 'active' : ''}">
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 10px; flex-wrap: wrap; gap: 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>` : ''}
|
||||
${isActive && !isCompleted ? `
|
||||
<button class="btn btn-action" onclick="buildStage()"
|
||||
${myState.cash < stage.cost ? 'disabled' : ''}>
|
||||
${myState.house.progress > 0 ? '⚡ Ускорить' : '🏗️ Начать строить'}
|
||||
</button>
|
||||
` : ''}
|
||||
${isCompleted ? '<div style="color: #4caf50; font-weight: bold;">✓ Готово</div>' : ''}
|
||||
</div>
|
||||
${isActive ? `
|
||||
@@ -641,12 +770,19 @@
|
||||
}
|
||||
const stage = houseStages[myState.house.stage];
|
||||
if (myState.cash < stage.cost) {
|
||||
log('Недостаточно средств', 'error');
|
||||
log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${stage.cost})`, 'error');
|
||||
return;
|
||||
}
|
||||
if (myState.house.progress === 0) {
|
||||
myState.cash -= stage.cost;
|
||||
}
|
||||
myState.house.progress += 10;
|
||||
if (myState.house.progress >= 100) {
|
||||
myState.house.stage++;
|
||||
myState.house.progress = 0;
|
||||
log(`Начато строительство: ${stage.name}`, 'success');
|
||||
log(`Этап "${stage.name}" завершён!`, 'success');
|
||||
}
|
||||
saveState();
|
||||
renderHouse();
|
||||
updateUI();
|
||||
}
|
||||
@@ -663,7 +799,10 @@
|
||||
<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 class="item-desc">
|
||||
Доход: $${biz.income}/сек
|
||||
${owned ? ` | Работников: ${myState.businesses[biz.id].workers} | Эффективность: x${myState.businesses[biz.id].efficiency.toFixed(1)}` : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-price">$${biz.cost.toLocaleString()}</div>
|
||||
<button class="btn ${owned ? 'btn-action' : 'btn-buy'}"
|
||||
@@ -679,24 +818,41 @@
|
||||
function buyBusiness(id) {
|
||||
const biz = businesses.find(b => b.id === id);
|
||||
if (myState.cash < biz.cost) {
|
||||
log('Недостаточно средств', 'error');
|
||||
log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${biz.cost})`, 'error');
|
||||
return;
|
||||
}
|
||||
myState.cash -= biz.cost;
|
||||
myState.businesses[id] = { workers: 1, efficiency: 1 };
|
||||
log(`Куплен бизнес: ${biz.name}`, 'success');
|
||||
saveState();
|
||||
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Введите номер:`);
|
||||
const hireCost = Math.floor(biz.cost / 10);
|
||||
const upgradeCost = Math.floor(biz.cost / 5);
|
||||
|
||||
const action = prompt(
|
||||
`Управление: ${biz.name}\n\n` +
|
||||
`Текущее состояние:\n` +
|
||||
`- Работников: ${myState.businesses[id].workers}\n` +
|
||||
`- Эффективность: x${myState.businesses[id].efficiency.toFixed(1)}\n` +
|
||||
`- Доход: $${Math.floor(biz.income * myState.businesses[id].workers * myState.businesses[id].efficiency)}/сек\n\n` +
|
||||
`Действия:\n` +
|
||||
`1. Нанять работника ($${hireCost.toLocaleString()})\n` +
|
||||
`2. Уволить работника (бесплатно)\n` +
|
||||
`3. Улучшить эффективность x1.5 ($${upgradeCost.toLocaleString()})\n\n` +
|
||||
`Введите номер действия:`
|
||||
);
|
||||
|
||||
if (action === '1') {
|
||||
const cost = biz.cost / 10;
|
||||
if (myState.cash < cost) { log('Недостаточно средств', 'error'); return; }
|
||||
myState.cash -= cost;
|
||||
if (myState.cash < hireCost) {
|
||||
log(`Недостаточно средств (нужно $${hireCost})`, 'error');
|
||||
return;
|
||||
}
|
||||
myState.cash -= hireCost;
|
||||
myState.businesses[id].workers++;
|
||||
log(`Нанят работник в ${biz.name}`, 'success');
|
||||
} else if (action === '2') {
|
||||
@@ -707,12 +863,15 @@
|
||||
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');
|
||||
if (myState.cash < upgradeCost) {
|
||||
log(`Недостаточно средств (нужно $${upgradeCost})`, 'error');
|
||||
return;
|
||||
}
|
||||
myState.cash -= upgradeCost;
|
||||
myState.businesses[id].efficiency *= 1.5;
|
||||
log(`Улучшена эффективность ${biz.name} до x${myState.businesses[id].efficiency.toFixed(1)}`, 'success');
|
||||
}
|
||||
saveState();
|
||||
renderBusinesses();
|
||||
updateUI();
|
||||
}
|
||||
@@ -744,13 +903,18 @@
|
||||
|
||||
function buyLuxury(id) {
|
||||
const item = luxuryItems.find(i => i.id === id);
|
||||
if (myState.luxury[id]) {
|
||||
log('У вас уже есть этот предмет', 'error');
|
||||
return;
|
||||
}
|
||||
if (myState.cash < item.cost) {
|
||||
log('Недостаточно средств', 'error');
|
||||
log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${item.cost})`, 'error');
|
||||
return;
|
||||
}
|
||||
myState.cash -= item.cost;
|
||||
myState.luxury[id] = true;
|
||||
log(`Куплено: ${item.name}`, 'success');
|
||||
saveState();
|
||||
renderLuxury();
|
||||
updateUI();
|
||||
}
|
||||
@@ -759,7 +923,6 @@
|
||||
// ИГРОВОЙ ЦИКЛ
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
function tick() {
|
||||
// Доход от бизнесов
|
||||
let totalIncome = 0;
|
||||
for (let id in myState.businesses) {
|
||||
const biz = businesses.find(b => b.id === id);
|
||||
@@ -771,7 +934,6 @@
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user